{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8f6c4aa7",
   "metadata": {},
   "source": [
    "# 基于Transformer的数学应用题求解器"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3043cb0d",
   "metadata": {},
   "source": [
    "## 1. 数据集准备\n",
    "\n",
    "我们使用 [Math23K](https://paperswithcode.com/dataset/math23k) 数据集，其中包含数学应用题以及对应的方程。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "4d99d358",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import math\n",
    "\n",
    "import numpy as np\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torch import Tensor\n",
    "from torch.utils.data import Dataset\n",
    "\n",
    "DEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "PAD_IDX = 1\n",
    "\n",
    "# Set seed.\n",
    "seed = 42\n",
    "np.random.seed(seed)\n",
    "torch.manual_seed(seed)\n",
    "torch.cuda.manual_seed(seed)\n",
    "torch.backends.cudnn.deterministic = True\n",
    "torch.backends.cudnn.benchmark = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c5abc787",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集大小: 22162\n",
      "测试集大小: 1000\n"
     ]
    }
   ],
   "source": [
    "# 读取Math23K数据集\n",
    "def read_math23k_data(path):\n",
    "    with open(path, \"r\", encoding=\"utf-8\") as f:\n",
    "        data = json.load(f)\n",
    "    problems = [item[\"text\"].split() for item in data]  # 将问题文本分割成单词\n",
    "    equations = [item[\"target_template\"][2:] for item in data]  # 移除方程的 'x=' 前缀\n",
    "    return problems, equations\n",
    "\n",
    "\n",
    "train_path, test_path = \"data/train.json\", \"data/test.json\"\n",
    "# 加载数据集\n",
    "train_problems, train_equations = read_math23k_data(\"data/train.json\")\n",
    "test_problems, test_equations = read_math23k_data(\"data/test.json\")\n",
    "\n",
    "print(f\"训练集大小: {len(train_problems)}\")\n",
    "print(f\"测试集大小: {len(test_problems)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "850398ad",
   "metadata": {},
   "source": [
    "让我们看一下数据集中的示例。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4c2b370e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "问题 1: ['甲数', '除以', '乙数', '的', '商是', 'temp_a', '，', '如果', '甲数', '增加', 'temp_b', '，', '则', '甲数', '是', '乙', '的', 'temp_c', '倍', '．', '原来', '甲数', '=', '．']\n",
      "方程 1: ['temp_b', '/', '(', 'temp_c', '-', 'temp_a', ')', '*', 'temp_a']\n",
      "--------------------\n",
      "问题 2: ['客车', '和', '货车', '分别', '从', 'A', '、', 'B', '两站', '同时', '相向', '开出', '，', 'temp_a', '小时', '后', '相遇', '．', '相遇', '后', '，', '两车', '仍', '按原', '速度', '前进', '，', '当', '它们', '相距', 'temp_b', '千米', '时', '，', '货车', '行', '了', '全程', '的', 'temp_c', '%', '，', '客车', '已行', '的', '路程', '与', '未行', '的', '路程', '比是', 'temp_d', '：', 'temp_e', '．', '求', 'A', '、', 'B', '两站', '间', '的', '路程', '．']\n",
      "方程 2: ['temp_b', '/', '(', 'temp_c', '+', '(', '(', 'temp_d', ')', '/', '(', 'temp_d', '+', 'temp_e', ')', ')', '-', '1', ')']\n",
      "--------------------\n",
      "问题 3: ['图书', '角有', '书', 'temp_a', '本', '，', '第一天', '借出', '了', 'temp_b', '，', '第二天', '又', '还', '回', 'temp_c', '本', '，', '现在', '图书', '角有', '多少', '本书', '？']\n",
      "方程 3: ['temp_a', '*', '(', '1', '-', 'temp_b', ')', '+', 'temp_c']\n",
      "--------------------\n"
     ]
    }
   ],
   "source": [
    "for i in range(3):\n",
    "    print(f\"问题 {i+1}: {train_problems[i]}\")\n",
    "    print(f\"方程 {i+1}: {train_equations[i]}\")\n",
    "    print(\"-\" * 20)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "796b984f",
   "metadata": {},
   "source": [
    "## 2. 数据预处理\n",
    "\n",
    "为了使用Transformer模型，我们需要对文本数据进行编码。我们将使用词汇表和Tokenization方法来处理这些文本。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f903676",
   "metadata": {},
   "source": [
    "### 2.1 创建词汇表\n",
    "\n",
    "我们将构建一个 Vocab 类，将每个 token 映射到一个唯一的整数 ID，并定义反向的映射。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "57bb4cea",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Source Vocab Size: 15452\n",
      "Target Vocab Size: 30\n"
     ]
    }
   ],
   "source": [
    "from collections import Counter\n",
    "\n",
    "\n",
    "class Vocab:\n",
    "    def __init__(self, sentence_list, min_count=1):\n",
    "        self.token2idx = {\"<unk>\": 0, \"<pad>\": 1, \"<bos>\": 2, \"<eos>\": 3}\n",
    "        self.build_vocab(sentence_list, min_count)\n",
    "\n",
    "    def build_vocab(self, sentence_list, min_count):\n",
    "        # 统计词频\n",
    "        token_counts = Counter([token for sentence in sentence_list for token in sentence])\n",
    "        # 对词汇按频率排序并为频率大于等于min_count的词汇分配索引\n",
    "        sorted_tokens = [token for token, count in token_counts.items() if count >= min_count]\n",
    "        sorted_tokens.sort(key=lambda token: token_counts[token], reverse=True)\n",
    "        for token in sorted_tokens:\n",
    "            self.token2idx[token] = len(self.token2idx)\n",
    "        # 创建反向索引\n",
    "        self.idx2token = {idx: token for token, idx in self.token2idx.items()}\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.idx2token)\n",
    "\n",
    "    def token_to_index(self, token):\n",
    "        if isinstance(token, str):\n",
    "            return self.token2idx.get(token, self.token2idx[\"<unk>\"])\n",
    "        else:\n",
    "            raise TypeError(\"Token should be a string\")\n",
    "\n",
    "    def index_to_token(self, index):\n",
    "        if isinstance(index, int):\n",
    "            return self.idx2token.get(index, \"<unk>\")\n",
    "        else:\n",
    "            raise TypeError(\"Index should be an integer\")\n",
    "\n",
    "    def to_tokens(self, indices):\n",
    "        return [self.index_to_token(index) for index in indices]\n",
    "\n",
    "    def to_indices(self, tokens):\n",
    "        return [self.token_to_index(token) for token in tokens]\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f\"Vocab(size={len(self)})\"\n",
    "\n",
    "    def __getitem__(self, tokens):\n",
    "        if not isinstance(tokens, (list, tuple)):\n",
    "            return self.token_to_index(tokens)\n",
    "        return [self.token_to_index(token) for token in tokens]\n",
    "\n",
    "\n",
    "src_vocab = Vocab(train_problems + test_problems)\n",
    "tgt_vocab = Vocab(train_equations + test_equations)\n",
    "print(f\"Source Vocab Size: {len(src_vocab)}\")\n",
    "print(f\"Target Vocab Size: {len(tgt_vocab)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3e185b5",
   "metadata": {},
   "source": [
    "下面我们将使用一些示例数据来演示 Vocab 的用法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "80debfdb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vocab 大小: 12\n",
      "--------------------\n",
      "token 到 index的映射:\n",
      "<unk>: 0\n",
      "<pad>: 1\n",
      "<bos>: 2\n",
      "<eos>: 3\n",
      "学习: 4\n",
      "我: 5\n",
      "爱: 6\n",
      "使: 7\n",
      "快乐: 8\n",
      "深度: 9\n",
      "很: 10\n",
      "有趣: 11\n",
      "--------------------\n",
      "example_tokens[0] 转换为index: [5, 6, 4]\n"
     ]
    }
   ],
   "source": [
    "example_tokens = [[\"我\", \"爱\", \"学习\"], [\"学习\", \"使\", \"我\", \"快乐\"], [\"深度\", \"学习\", \"很\", \"有趣\"]]\n",
    "example_vocab = Vocab(example_tokens)\n",
    "print(f\"vocab 大小: {len(example_vocab)}\")\n",
    "print(\"-\" * 20)\n",
    "print(\"token 到 index的映射:\")\n",
    "for token, idx in example_vocab.token2idx.items():\n",
    "    print(f\"{token}: {idx}\")\n",
    "print(\"-\" * 20)\n",
    "print(f\"example_tokens[0] 转换为index: {example_vocab[example_tokens[0]]}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cef535b0",
   "metadata": {
    "lines_to_next_cell": 2
   },
   "source": [
    "### 2.2 生成数据集\n",
    "\n",
    "我们要对数据先进行以下预处理：\n",
    "\n",
    "1. **添加特殊标记（Adding Special Tokens）**：在输入序列的开头和末尾添加特殊标记，如开始标记（`<bos>`）和结束标记（`<eos>`），以及填充标记（`<pad>`）等。这些标记有助于模型更好地理解输入序列的边界和结构。\n",
    "\n",
    "2. **数据向量化（Vectorization）**：将文本数据转换为模型可以处理的数值张量形式。\n",
    "\n",
    "3. **填充和截断（Padding and Truncation）**：Transformer 模型对于输入序列的长度通常是固定的，因此需要对输入序列进行填充（padding）或截断（truncation），使得所有序列具有相同的长度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "08d92e33",
   "metadata": {},
   "outputs": [],
   "source": [
    "def preprocess_sentence(sentence, vocab, max_len):\n",
    "    # 1. 添加特殊符号\n",
    "    sentence = [\"<bos>\"] + sentence + [\"<eos>\"]\n",
    "    # 2. 将词汇转换为索引\n",
    "    indices = vocab[sentence]\n",
    "    # 3. 将索引转换为张量\n",
    "    indices = torch.tensor(indices)\n",
    "    # 4. 填充PAD\n",
    "    if len(indices) > max_len:\n",
    "        indices = indices[:max_len]\n",
    "    else:\n",
    "        pad_size = max_len - len(indices)\n",
    "        indices = F.pad(indices, (0, pad_size), value=vocab[\"<pad>\"])\n",
    "    return indices\n",
    "\n",
    "\n",
    "class Math23kDataset(Dataset):\n",
    "    def __init__(self, problems, equations, src_vocab, tgt_vocab):\n",
    "        src_max_len, tgt_max_len = 120, 50\n",
    "        src_data = [preprocess_sentence(sentence, src_vocab, src_max_len) for sentence in problems]\n",
    "        tgt_data = [preprocess_sentence(sentence, tgt_vocab, tgt_max_len) for sentence in equations]\n",
    "        self.src_data = torch.stack(src_data).to(DEVICE)\n",
    "        self.tgt_data = torch.stack(tgt_data).to(DEVICE)\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.src_data)\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        return self.src_data[idx], self.tgt_data[idx]\n",
    "\n",
    "\n",
    "train_dataset = Math23kDataset(train_problems, train_equations, src_vocab, tgt_vocab)\n",
    "test_dataset = Math23kDataset(test_problems, test_equations, src_vocab, tgt_vocab)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "44972872",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "src example: tensor([  2, 207, 354, 212,   5, 469,   6,   4,  55, 207, 206,   7,   4, 225,\n",
      "        207,  15,  78,   5,  11,  54,  10,  71, 207,  19,  10,   3,   1,   1,\n",
      "          1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,\n",
      "          1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,\n",
      "          1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,\n",
      "          1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,\n",
      "          1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,\n",
      "          1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,\n",
      "          1,   1,   1,   1,   1,   1,   1,   1], device='cuda:0')\n",
      "src text: <bos> 甲数 除以 乙数 的 商是 temp_a ， 如果 甲数 增加 temp_b ， 则 甲数 是 乙 的 temp_c 倍 ． 原来 甲数 = ． <eos> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad>\n",
      "--------------------\n",
      "tgt example: tensor([ 2,  5,  6,  7, 10, 11,  4,  8,  9,  4,  3,  1,  1,  1,  1,  1,  1,  1,\n",
      "         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,\n",
      "         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1],\n",
      "       device='cuda:0')\n",
      "tgt text: <bos> temp_b / ( temp_c - temp_a ) * temp_a <eos> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad> <pad>\n"
     ]
    }
   ],
   "source": [
    "src_example, tgt_example = train_dataset[0]\n",
    "print(\"src example:\", src_example)\n",
    "print(\"src text:\", \" \".join(src_vocab.to_tokens(src_example.tolist())))\n",
    "print(\"-\" * 20)\n",
    "print(\"tgt example:\", tgt_example)\n",
    "print(\"tgt text:\", \" \".join(tgt_vocab.to_tokens(tgt_example.tolist())))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d7efb821",
   "metadata": {},
   "source": [
    "## 3. 构建 Transformer 模型\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19227ae8",
   "metadata": {},
   "source": [
    "### 3.1 位置编码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "404e49eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "class PositionalEncoding(nn.Module):\n",
    "    def __init__(self, emb_size: int, dropout: float, maxlen: int = 5000):\n",
    "        super(PositionalEncoding, self).__init__()\n",
    "        den = torch.exp(-torch.arange(0, emb_size, 2) * math.log(10000) / emb_size)\n",
    "        pos = torch.arange(0, maxlen).reshape(maxlen, 1)\n",
    "        pos_embedding = torch.zeros((maxlen, emb_size))\n",
    "        pos_embedding[:, 0::2] = torch.sin(pos * den)\n",
    "        pos_embedding[:, 1::2] = torch.cos(pos * den)\n",
    "\n",
    "        self.dropout = nn.Dropout(dropout)\n",
    "        self.register_buffer(\"pos_embedding\", pos_embedding)\n",
    "\n",
    "    def forward(self, token_embedding: Tensor):\n",
    "        \"\"\"\n",
    "        Shape:\n",
    "            token_embedding: [batch_size, seq_len, emb_size]\n",
    "            output: [batch_size, seq_len, emb_size]\n",
    "        \"\"\"\n",
    "        return self.dropout(token_embedding + self.pos_embedding[: token_embedding.size(1), :])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d47cacc3",
   "metadata": {},
   "source": [
    "### 3.2 Seq2Seq 模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "832436f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "class TokenEmbedding(nn.Module):\n",
    "    def __init__(self, vocab_size: int, emb_size):\n",
    "        super(TokenEmbedding, self).__init__()\n",
    "        self.embedding = nn.Embedding(vocab_size, emb_size)\n",
    "        self.emb_size = emb_size\n",
    "\n",
    "    def forward(self, tokens: Tensor):\n",
    "        return self.embedding(tokens.long()) * math.sqrt(self.emb_size)\n",
    "\n",
    "\n",
    "class Seq2SeqTransformer(nn.Module):\n",
    "    def __init__(\n",
    "        self,\n",
    "        num_encoder_layers: int,\n",
    "        num_decoder_layers: int,\n",
    "        emb_size,\n",
    "        nhead,\n",
    "        src_vocab_size,\n",
    "        tgt_vocab_size,\n",
    "        dim_feedforward: int = 512,\n",
    "        dropout: float = 0.1,\n",
    "    ):\n",
    "        super(Seq2SeqTransformer, self).__init__()\n",
    "\n",
    "        self.positional_encoding = PositionalEncoding(emb_size, dropout=dropout)\n",
    "        self.src_tok_emb = TokenEmbedding(src_vocab_size, emb_size)\n",
    "        self.tgt_tok_emb = TokenEmbedding(tgt_vocab_size, emb_size)\n",
    "        self.transformer = nn.Transformer(\n",
    "            d_model=emb_size,\n",
    "            nhead=nhead,\n",
    "            num_encoder_layers=num_encoder_layers,\n",
    "            num_decoder_layers=num_decoder_layers,\n",
    "            dim_feedforward=dim_feedforward,\n",
    "            dropout=dropout,\n",
    "            batch_first=True,\n",
    "        )\n",
    "        self.generator = nn.Linear(emb_size, tgt_vocab_size)\n",
    "\n",
    "    def forward(\n",
    "        self,\n",
    "        src: Tensor,\n",
    "        trg: Tensor,\n",
    "        src_mask: Tensor,\n",
    "        tgt_mask: Tensor,\n",
    "        src_padding_mask: Tensor,\n",
    "        tgt_padding_mask: Tensor,\n",
    "        memory_padding_mask: Tensor,\n",
    "    ):\n",
    "        src_emb = self.positional_encoding(self.src_tok_emb(src))\n",
    "        tgt_emb = self.positional_encoding(self.tgt_tok_emb(trg))\n",
    "        outs = self.transformer(\n",
    "            src_emb, tgt_emb, src_mask, tgt_mask, None, src_padding_mask, tgt_padding_mask, memory_padding_mask\n",
    "        )\n",
    "        return self.generator(outs)\n",
    "\n",
    "    def encode(self, src: Tensor, src_mask: Tensor, src_key_padding_mask=None):\n",
    "        return self.transformer.encoder(self.positional_encoding(self.src_tok_emb(src)), src_mask, src_key_padding_mask)\n",
    "\n",
    "    def decode(self, tgt: Tensor, memory: Tensor, tgt_mask: Tensor):\n",
    "        return self.transformer.decoder(self.positional_encoding(self.tgt_tok_emb(tgt)), memory, tgt_mask)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9e5f2ad",
   "metadata": {},
   "source": [
    "## 4. 训练模型"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49c443b7",
   "metadata": {},
   "source": [
    "### 4.1 定义训练函数和评估函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "cf6ab5c9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False,  True,  True,  ...,  True,  True,  True],\n",
      "        [False, False,  True,  ...,  True,  True,  True],\n",
      "        [False, False, False,  ...,  True,  True,  True],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False,  True,  True],\n",
      "        [False, False, False,  ..., False, False,  True],\n",
      "        [False, False, False,  ..., False, False, False]], device='cuda:0')\n",
      "tensor([[False, False, False, False, False, False, False, False, False, False,\n",
      "         False, False, False, False, False, False, False, False, False, False,\n",
      "         False, False, False, False, False, False,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True],\n",
      "        [False, False, False, False, False, False, False, False, False, False,\n",
      "         False, False, False, False, False, False, False, False, False, False,\n",
      "         False, False, False, False, False, False, False, False, False, False,\n",
      "         False, False, False, False, False, False, False, False, False, False,\n",
      "         False, False, False, False, False, False, False, False, False, False,\n",
      "         False, False, False, False, False, False, False, False, False, False,\n",
      "         False, False, False, False, False, False,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True,\n",
      "          True,  True,  True,  True,  True,  True,  True,  True,  True,  True]],\n",
      "       device='cuda:0')\n"
     ]
    }
   ],
   "source": [
    "def create_mask(src, tgt):\n",
    "    src_seq_len = src.shape[1]\n",
    "    tgt_seq_len = tgt.shape[1]\n",
    "\n",
    "    src_mask = torch.zeros((src_seq_len, src_seq_len), dtype=torch.bool, device=DEVICE)\n",
    "    tgt_mask = torch.ones((tgt_seq_len, tgt_seq_len), dtype=torch.bool, device=DEVICE).triu_(diagonal=1)\n",
    "\n",
    "    src_padding_mask = src == PAD_IDX\n",
    "    tgt_padding_mask = tgt == PAD_IDX\n",
    "    return src_mask, tgt_mask, src_padding_mask, tgt_padding_mask\n",
    "\n",
    "\n",
    "batch_src, batch_tgt = train_dataset[0:2]\n",
    "src_mask, tgt_mask, src_padding_mask, tgt_padding_mask = create_mask(batch_src, batch_tgt)\n",
    "print(src_mask)\n",
    "print(tgt_mask)\n",
    "print(src_padding_mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "5dd62599",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 训练和评估函数\n",
    "def train_epoch(model, train_loader, optimizer, loss_fn):\n",
    "    model.train()\n",
    "    losses = 0\n",
    "    for src, tgt in train_loader:\n",
    "        src, tgt = src.to(DEVICE), tgt.to(DEVICE)\n",
    "        tgt_input = tgt[:, :-1]\n",
    "        src_mask, tgt_mask, src_padding_mask, tgt_padding_mask = create_mask(src, tgt_input)\n",
    "\n",
    "        logits = model(src, tgt_input, src_mask, tgt_mask, src_padding_mask, tgt_padding_mask, src_padding_mask)\n",
    "        optimizer.zero_grad()\n",
    "\n",
    "        tgt_out = tgt[:, 1:]\n",
    "        loss = loss_fn(logits.reshape(-1, logits.shape[-1]), tgt_out.reshape(-1))\n",
    "        loss.backward()\n",
    "\n",
    "        torch.nn.utils.clip_grad_norm_(model.parameters(), 1)\n",
    "\n",
    "        optimizer.step()\n",
    "        losses += loss.item()\n",
    "\n",
    "    return losses / len(train_loader)\n",
    "\n",
    "\n",
    "def evaluate(model, val_loader, loss_fn):\n",
    "    model.eval()\n",
    "    losses = 0\n",
    "    for src, tgt in val_loader:\n",
    "        src, tgt = src.to(DEVICE), tgt.to(DEVICE)\n",
    "        tgt_input = tgt[:, :-1]\n",
    "        src_mask, tgt_mask, src_padding_mask, tgt_padding_mask = create_mask(src, tgt_input)\n",
    "\n",
    "        logits = model(src, tgt_input, src_mask, tgt_mask, src_padding_mask, tgt_padding_mask, src_padding_mask)\n",
    "\n",
    "        tgt_out = tgt[:, 1:]\n",
    "        loss = loss_fn(logits.reshape(-1, logits.shape[-1]), tgt_out.reshape(-1))\n",
    "        losses += loss.item()\n",
    "\n",
    "    return losses / len(val_loader)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c9b51e1",
   "metadata": {},
   "source": [
    "### 4.2 设置超参数和初始化模型\n",
    "\n",
    "我们将定义模型、优化器和损失函数，并设置训练所需的参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "32660d5d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total params: 3.83747 M\n"
     ]
    }
   ],
   "source": [
    "# 模型超参数\n",
    "SRC_VOCAB_SIZE = len(src_vocab)\n",
    "TGT_VOCAB_SIZE = len(tgt_vocab)\n",
    "EMB_SIZE = 128\n",
    "NHEAD = 8  # 注意力头数\n",
    "FFN_HID_DIM = 512  # FeedForward隐藏层维度\n",
    "NUM_LAYERS = 4  # Transformer层数\n",
    "\n",
    "BATCH_SIZE = 128\n",
    "LEARNING_RATE = 0.0008\n",
    "DROP_OUT = 0.1\n",
    "\n",
    "model = Seq2SeqTransformer(\n",
    "    NUM_LAYERS, NUM_LAYERS, EMB_SIZE, NHEAD, SRC_VOCAB_SIZE, TGT_VOCAB_SIZE, FFN_HID_DIM, DROP_OUT\n",
    ")\n",
    "\n",
    "total_params = sum(p.numel() for p in model.parameters())\n",
    "print(\"Total params:\", total_params / 1e6, \"M\")\n",
    "\n",
    "model = model.to(DEVICE)\n",
    "\n",
    "criterion = nn.CrossEntropyLoss(ignore_index=tgt_vocab[\"<pad>\"])\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a31595e5",
   "metadata": {},
   "source": [
    "### 4.3 开始训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "6aea8ebb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 0, Train loss: 1.194, Val loss: 0.907, Epoch time = 10.355s\n",
      "Epoch: 1, Train loss: 0.891, Val loss: 0.812, Epoch time = 10.252s\n",
      "Epoch: 2, Train loss: 0.811, Val loss: 0.734, Epoch time = 10.252s\n",
      "Epoch: 3, Train loss: 0.759, Val loss: 0.726, Epoch time = 10.252s\n",
      "Epoch: 4, Train loss: 0.720, Val loss: 0.686, Epoch time = 10.251s\n",
      "Epoch: 5, Train loss: 0.680, Val loss: 0.647, Epoch time = 10.251s\n",
      "Epoch: 6, Train loss: 0.650, Val loss: 0.638, Epoch time = 10.251s\n",
      "Epoch: 7, Train loss: 0.624, Val loss: 0.630, Epoch time = 10.251s\n",
      "Epoch: 8, Train loss: 0.603, Val loss: 0.601, Epoch time = 10.251s\n",
      "Epoch: 9, Train loss: 0.583, Val loss: 0.576, Epoch time = 10.252s\n",
      "Epoch: 10, Train loss: 0.564, Val loss: 0.570, Epoch time = 10.252s\n",
      "Epoch: 11, Train loss: 0.547, Val loss: 0.556, Epoch time = 10.251s\n",
      "Epoch: 12, Train loss: 0.532, Val loss: 0.556, Epoch time = 10.252s\n",
      "Epoch: 13, Train loss: 0.517, Val loss: 0.540, Epoch time = 10.251s\n",
      "Epoch: 14, Train loss: 0.500, Val loss: 0.536, Epoch time = 10.250s\n",
      "Epoch: 15, Train loss: 0.489, Val loss: 0.526, Epoch time = 10.251s\n",
      "Epoch: 16, Train loss: 0.482, Val loss: 0.549, Epoch time = 10.250s\n",
      "Epoch: 17, Train loss: 0.467, Val loss: 0.534, Epoch time = 10.251s\n",
      "Epoch: 18, Train loss: 0.456, Val loss: 0.538, Epoch time = 10.252s\n",
      "Epoch: 19, Train loss: 0.445, Val loss: 0.544, Epoch time = 10.256s\n",
      "Epoch: 20, Train loss: 0.435, Val loss: 0.540, Epoch time = 10.250s\n",
      "Epoch: 21, Train loss: 0.429, Val loss: 0.525, Epoch time = 10.250s\n",
      "Epoch: 22, Train loss: 0.418, Val loss: 0.526, Epoch time = 10.252s\n",
      "Epoch: 23, Train loss: 0.412, Val loss: 0.506, Epoch time = 10.252s\n",
      "Epoch: 24, Train loss: 0.401, Val loss: 0.533, Epoch time = 10.252s\n",
      "Epoch: 25, Train loss: 0.394, Val loss: 0.514, Epoch time = 10.251s\n",
      "Epoch: 26, Train loss: 0.382, Val loss: 0.515, Epoch time = 10.252s\n",
      "Epoch: 27, Train loss: 0.377, Val loss: 0.516, Epoch time = 10.251s\n",
      "Epoch: 28, Train loss: 0.369, Val loss: 0.507, Epoch time = 10.253s\n",
      "Epoch: 29, Train loss: 0.361, Val loss: 0.537, Epoch time = 10.251s\n"
     ]
    }
   ],
   "source": [
    "from timeit import default_timer as timer\n",
    "from torch.utils.data import DataLoader\n",
    "\n",
    "NUM_EPOCHS = 30\n",
    "\n",
    "train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)\n",
    "val_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE)\n",
    "\n",
    "train_loss_list, valid_loss_list = [], []\n",
    "\n",
    "for epoch in range(NUM_EPOCHS):\n",
    "    start_time = timer()\n",
    "    train_loss = train_epoch(model, train_loader, optimizer, criterion)\n",
    "    val_loss = evaluate(model, val_loader, criterion)\n",
    "    end_time = timer()\n",
    "    train_loss_list.append(train_loss)\n",
    "    valid_loss_list.append(val_loss)\n",
    "    print(\n",
    "        (\n",
    "            f\"Epoch: {epoch}, Train loss: {train_loss:.3f}, Val loss: {val_loss:.3f}, \"\n",
    "            f\"Epoch time = {(end_time - start_time):.3f}s\"\n",
    "        )\n",
    "    )\n",
    "\n",
    "# 保存模型\n",
    "torch.save(model.state_dict(), \"model.pth\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "68ec1b91",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABpwAAAS0CAYAAAB9vatGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAB7CAAAewgFu0HU+AAEAAElEQVR4nOzdeZxVdf0/8NdlR0AQFERABc3UtNwt09Jc2nBvcV/LXfGb/bJMza3UbHHfMvct941SSsXcyS0lrVRcQEFEVPZtmN8fEwN3WAdm5txhns/HYx7d877n3PO66PgHrz6fU6qurq4OAAAAAAAALKVWRQcAAAAAAACgeVM4AQAAAAAAsEwUTgAAAAAAACwThRMAAAAAAADLROEEAAAAAADAMlE4AQAAAAAAsEwUTgAAAAAAACwThRMAAAAAAADLROEEAAAAAADAMlE4AQAAAAAAsEwUTgAAAAAAACwThRMAAAAAAADLROEEAAAAAADAMlE4AQAAAAAAsEwUTgAAAAAAACwThRMAAAAAAADLpE3RAWh806ZNyyuvvJIkWWWVVdKmjX/sAAAAAADQUs2aNSsffvhhkmTDDTdMhw4dlvkzNQ8twCuvvJItttii6BgAAAAAAECFGTZsWDbffPNl/hxb6gEAAAAAALBMrHBqAVZZZZXa18OGDUvv3r0LTAMAAAAAABRp9OjRtTujzdshLAuFUwsw7zObevfunb59+xaYBgAAAAAAqBTzdgjLwpZ6AAAAAAAALBOFEwAAAAAAAMtE4QQAAAAAAMAyUTgBAAAAAACwTBROAAAAAAAALBOFEwAAAAAAAMtE4QQAAAAAAMAyUTgBAAAAAACwTBROAAAAAAAALBOFEwAAAAAAAMukTdEBAAAAAABonqZNm5ZPPvkkU6ZMSVVVVdFxoEVo3bp12rVrlxVXXDGdO3dOq1aVsbZI4QQAAAAAQL1UV1dn9OjR+fTTT4uOAi3OrFmzMn369EycODGlUil9+vRJly5dio6lcAIAAAAAoH4++uij+cqmNm38dTM0haqqqlRXVyepKX/fe++9iiid/BcAAAAAAIAlNmPGjHz44Ye1xz179ky3bt3SunXrAlNBy1FdXZ0pU6Zk/PjxmTRpUm3ptM466xS6vV5lbOwHAAAAAECzMGnSpNrXPXr0SI8ePZRN0IRKpVI6deqUvn37pnPnzklqSqh5fzeLoHACAAAAAGCJTZ48ufb1iiuuWGASaNlKpVK6d+9eezxhwoQC0yicAAAAAACohxkzZiSp+cvu9u3bF5wGWrYVVlghpVIpydzfzaIonAAAAAAAWGKzZ89OkrRu3br2L7qBYpRKpdotLauqqgrNonACAAAAAABgmSicAAAAAAAAWCYKJwAAAAAAAJaJwgkAAAAAAIBlonACAAAAAABgmSicAAAAAACApVIqlVIqlXLaaacVmmPbbbdNqVTKtttuW2iOlkzhBAAAAAAAwDJROAEAAAAAQIW69tpra1cRvf3220XHgYVqU3QAAAAAAACgeaquri46AhXCCicAAAAAAACWicIJAAAAAACAZaJwAgAAAACACjN06NCUSqUcfPDBtbP+/fvXPs9pzs/QoUNr3z/ooINSKpWy5pprJklGjx6dE088MZ/73OfSpUuX+c7/+OOPc80112S//fbL+uuvn86dO6ddu3ZZddVV8/Wvfz1XXnllZsyYscicc3Kcdtpp871X9/lTs2fPzpVXXpmtttoqK620Ujp16pTPf/7z+eUvf5kpU6Ysyx/XEnviiSey//77Z80110yHDh3SrVu3bLzxxjn55JPz4YcfLvLaadOm5cILL8y2226bVVZZJW3btk337t3z2c9+Nt/85jfzu9/9bqHP2Xr++edz6KGHZp111kmnTp3SoUOH9OvXL5tuummOPvro3Hfffc1+e0LPcAIAAAAAgOXMM888k5133jnjxo1b6Dkbb7xx3nnnnfnmH3zwQYYMGZIhQ4bk8ssvz5///Oesuuqqy5RnypQp2WmnnfLwww+XzV955ZW88sorue+++/LII4+kU6dOy3SfhZk9e3aOO+64XHLJJWXz6dOn56WXXspLL72Uiy++OLfffnt23HHH+a4fPXp0dthhh7z66qtl848//jgff/xx/vvf/+bBBx/M+++/n9/85jdl5/z+97/Pj3/848yePbtsPmrUqIwaNSovvPBCLr300kycODGdO3duoG/c9Fps4TR27NgMGzYsw4YNyz/+8Y/84x//yEcffZQkOfDAA3Pttdc2yH0+/fTTPPDAA/nb3/6WF154IW+//XamTJmSbt26ZYMNNsjAgQNz6KGHplu3bg1yPwAAAAAAmr/NN988r7zySu69996cfPLJSZKHHnooq622Wtl5/fv3n+/aSZMmZc8998y0adPy85//PDvuuGNWWGGFvPLKK+ndu3fteVVVVdlyyy0zcODAbLzxxunVq1dmzJiRt956KzfeeGMefPDBvPjii9lrr73KVkYtjR/+8Id55plncuCBB+Z73/teVl111bz77rv59a9/naeffjrDhg3LWWedlbPPPnuZ7rMwP/3pT2vLpv79++fEE0/MJptsksmTJ+e+++7LxRdfnE8//TQDBw7MsGHD8oUvfKHs+mOPPba2bNpvv/2yxx57ZLXVVkvr1q0zevToPPfcc7n33nvnu+/LL79cWzb1798/xxxzTDbaaKN07949EydOzH/+8588+uijC7y2uWmxhVOvXr0a/R5/+ctfsvvuu2f69OnzvTdu3LgMHTo0Q4cOzW9+85vcfPPN2W677Ro9EwAAAABAY5s9O/nf/7+/xejRI2nVgA+x6dSpUzbYYIM899xztbN11lmndru8Rfnoo4/SuXPnPPHEE2XFyeabb1523iOPPJLPfOYz812/1VZbZd99980111yTQw45JI899lgefvjhbL/99kv9fZ566qnccMMN2W+//Wpnm2yySb75zW9ms802y/Dhw/OHP/whZ555Ztq0adjq4pVXXslvf/vbJMkGG2yQxx9/vGwRyLbbbpuddtop3/72tzNjxowcdthhefbZZ2vfnzZtWu67774kyQknnDDfCqYk2XnnnXP66adn/PjxZfM77rgjs2fPTqdOnfL000/P101ss802+cEPfpBPP/00K6ywQkN95UK02MJpXquvvnrWXXfdDBkypEE/96OPPsr06dPTqlWr7LjjjvnGN76RL3zhC+nWrVtGjRqVm266KX/6058yZsyYDBw4ME8++WQ22mijBs0AAAAAANDUPvoo6dmz6BRNa+zYZJVVik4x109+8pP5VunUtaCyaV4HH3xwLrzwwrz00ku55557lqlw2mOPPcrKpjnat2+fY445JkcccUQ++uijvPrqq/n85z+/1PdZkMsuu6x2O7urrrpqgTuOfeMb38ghhxySq666qnZntDkF3fjx4zNz5swkyVe+8pVF3qt79+5lx2PGjElSUxYuaiFM165dl/j7VKoG7Fubl1NPPTX3339/xowZk3feeSdXXHFFg9+jbdu2Ofzww/PWW2/lwQcfzPHHH5/tttsuG2+8cXbeeefceuutufDCC5PU7F/5ox/9qMEzAAAAAADQ8uy77771Or+6ujpjxozJf//73wwfPrz2p0+fPkmSf/7zn42WZ9NNN619PWLEiGW6z4L87W9/S5J87nOfy5ZbbrnQ8374wx/Od02S9OjRI+3atUuS3HDDDZk1a9YS33vOFoavvvpqhg0bVq/czU2LLZxOP/30DBw4sFG31vv+97+fyy+/PKuvvvpCzzn22GOz2WabJUkee+yxRT7ADQAAAAAAFqdz584ZMGDAEp07ePDgDBw4MF27dk3v3r3z2c9+NhtuuGHtz+DBg5Nkmf/uet11113oe/OuCpo4ceIy3aeu6dOn5/XXX0+SRZZNSbLxxhunbdu2SZLhw4fXztu3b5/vf//7SWq2yFt77bXzk5/8JH/+85/zySefLPIz995777Rt2zbTp0/Pl7/85ey88865/PLLM3z48FRXVy/DN6s8LbZwqiTbbrttkmT27Nl56623ig0DAAAAAECztqAt4+qqrq7OD37wgwwcODCDBw9ebNEzderUZcq0qOcTtZrn4VdVVVXLdJ+6Pv7449rXPRezz2Pbtm3To0ePJJnvWUwXX3xxdt555yTJO++8k/POOy/f/va306NHj2y++eY577zz8umnn873meuuu25uueWWrLTSSpk1a1YeeOCBHHnkkdlwww3Ts2fP7L///nn88ceX9WtWBM9wqgDTp0+vfd26desCkwAAAAAALLsePWqeadSS/K+nqAhL8vfMV199df74xz8mSTbaaKMcf/zx2XLLLdOnT5+ssMIKtZ9xwAEH5IYbblguVuOUSqWlvnbFFVfMfffdl2HDhuW2227L0KFD89JLL6WqqirPPfdcnnvuufzmN7/JPffcky996Utl1+65557ZYYcd8qc//SkPPfRQHn/88Xz44YcZN25cbrzxxtx444058MADc/XVV5eVb82NwqkCPPbYY0lq2tO111673tePGjVqke+PHj16qXIBAAAAACyNVq2SVVYpOgWL8oc//CFJsvbaa+epp55Kx44dF3he3ZU+zc1KK61U+/qDDz5Y5LmzZs3KRx99lKR8m795bbHFFtliiy2S1Gz/N3To0Fx77bW56667Mnbs2Oy5555588035/vz7Nq1aw477LAcdthhSZLXXnst9957by666KK8//77ue6667Lxxhtn0KBBS/1di9Z8q7LlxODBg/Pyyy8nSb7+9a9nxRVXrPdn9OvXb5E/c/7lBwAAAACgeVmWVTmL8q9//StJsssuuyy0bKqurs4LL7zQKPdvKu3bt89nPvOZJMmzzz67yHNffPHFzJw5M0mywQYbLPazu3Tpkp133jl33nlnjjvuuCQ1C0CeeOKJxV673nrr5ac//WmeeeaZdOrUKUly2223Lfa6SqZwKtD48eNz9NFHJ6lZ4njGGWcUnAgAAAAAgErSoUOH2tfzPp5lWc2aNStJMnny5IWec++99y4XO2jtsMMOSWpKtmHDhi30vKuuumq+a5bU9ttvX/t63LhxS3xdv379ss4669T7ukqkcCpIVVVV9t1337zzzjtJkpNPPjkbb7zxUn3WyJEjF/mzqF8gAAAAAAAqV+/evWtfv/nmmw32uXNW/dx///0L3DbvzTffrF0w0dwdeeSRtc9GOuywwzJhwoT5zhkyZEjtM6222GKLbL755rXvjRgxovbROAszZMiQ2tf9+/evfX3PPffkk08+Weh1I0eOzL///e/5rmuOPMOpIEcddVQefPDBJMnAgQNzyimnLPVn9e3bt6FiAQAAAABQQTbeeON06NAh06ZNyymnnJK2bdtmjTXWqC1Q+vTps9At8RblgAMOyP/7f/8v77//fr70pS/lxBNPzAYbbJBp06blkUceyfnnn5/p06dnk002afbb6m244YY54YQTct555+Wf//xnNtlkk5x44onZeOONM3ny5Nx///258MILU1VVlXbt2uWKK64ou/7dd9/Ndtttl/XXXz+77757Nttss/Tp0ydJTWH0pz/9qXY7vI022ihbbrll7bXnn39+9t1333z729/O1772tay33nrp2rVrPv744zz33HO56KKLMnXq1CTJEUcc0UR/Io1D4VSAn/3sZ7nyyiuTJNtss01uu+22tG7duuBUAAAAAABUmi5duuS4447Lr3/967zwwgvZaaedyt5/9NFHs+2229b7cwcNGpS//vWvGTJkSP773//m0EMPLXu/Y8eOuf766zN48OBmXzglyTnnnJPJkyfn0ksvzZtvvpnDDjtsvnO6du2a2267LRtttNECP+PVV1/Nq6++utB7rLvuurnrrrvme+7WlClTcvvtt+f2229f4HWtWrXK6aefnt12222Jv08lUjg1sXPPPTfnnHNOkmSTTTbJAw88sFTtM8tmxozkyiuTN9+c+/Pww8mqqxadDAAAAACg3DnnnJPPfOYzuf766/Ovf/0rn376aaqqqpbpM9u2bZvBgwfnsssuy/XXX59XX3011dXV6dOnT3bYYYcMGjQo6667bgYPHtxA36JYrVq1yiWXXJK99torV1xxRR5//PF88MEHad++fQYMGJBvfetbOf7447PKKqvMd+0222yToUOH5qGHHsozzzyTkSNH5oMPPsi0adPSvXv3fOELX8gee+yRgw46KO3bty+79pZbbskDDzyQoUOH5tVXX82YMWMybty4dOjQIWussUa+8pWv5IgjjsjnP//5pvqjaDSl6urq6qJDVIK33367dn/EAw88MNdee22D3+PSSy+t3fNyvfXWy9///vesvPLKDX6fukaNGpV+/folqVneZwu+ZPbsZIUVknmfsff448nWWxeXCQAAAACag9dffz2zZs1KmzZtap8DBBRnaX4nG6M3aLXMn8ASueGGG3LMMcckSQYMGJC//e1vTVI2sWCtWiV1n7/WgM/bAwAAAACAFkXh1ATuuuuuHHzwwamurk7fvn3z8MMPZ7XVVis6Vou31lrlxwonAAAAAABYOgqnZXDttdemVCqlVCrltNNOW+A5Q4YMyd57752qqqr07Nkzf/vb37Lmmms2aU4WTOEEAAAAAAANo03RAYryxBNP5I033qg9HjduXO3rN954Y75nOB100EH1vsczzzyT3XffPTNmzEjbtm3z+9//PjNnzszw4cMXek3fvn3TrVu3et+L+qtbOI0YUUwOAAAAAABo7lps4XTVVVfluuuuW+B7Tz75ZJ588smy2dIUTg8++GCmTJmSJJk5c2b23XffxV5zzTXXLNW9qD8rnAAAAAAAoGHYUo8Wq27h9OGHycSJxWQBAAAAAIDmrFRdXV1ddAga16hRo9KvX78kyciRI9O3b9+CE1WGadOSFVZI5v0NePHFZKONCosEAAAAABXv9ddfz6xZs9KmTZt85jOfKToOtHhL8zvZGL2BFU60WB06JH36lM9sqwcAAAAAAPWncKJF8xwnAAAAAABYdgonWjSFEwAAAAAALDuFEy2awgkAAAAAAJadwokWTeEEAAAAAADLTuFEi1a3cHr33WTmzGKyAAAAAABAc6VwokWrWzjNnp28804xWQAAAAAAoLlSONGirbRSzc+8bKsHAAAAAAD1o3CixfMcJwAAAAAAWDYKJ1q8AQPKjxVOAAAAAABQPwonWjwrnAAAAAAAYNkonGjxFE4AAAAAALBsFE60eHULpxEjkurqYrIAAAAAAFSiUqmUUqmU0047bb73hg4dWvv+0KFDl/oep512Wu3nNEZOGpfCiRavbuE0ZUrywQfFZAEAAAAAgOZI4USL16dP0r59+cy2egAAAAAAsOQUTrR4rVol/fuXzxROAAAAAABLZtttt011dXWqq6uz7bbbFh2HgiicIPNvq6dwAgAAAACAJadwgiicAAAAAABgWSicIMmAAeXHCicAAAAAoEhTpkxJly5dUiqVsu+++y72/KeffjqlUimlUimXXnpp2Xsff/xxrrnmmuy3335Zf/3107lz57Rr1y6rrrpqvv71r+fKK6/MjBkzljrr0KFDa+89dOjQhZ43atSoHH300RkwYEA6dOiQ1VZbLbvsskv+9re/LfW9l8bs2bNz44035lvf+lZWXXXVtGvXLqusskq22267XHrppYv9s3j//ffz05/+NJtsskm6du2atm3bplevXtlwww2z995759prr82ECRMWeO3dd9+d3XbbLX379k379u3TpUuXDBgwINtss01OOeWUDBs2rDG+cpNoU3QAqARWOAEAAAAAlWSFFVbIbrvtlhtvvDH33ntvJk+enE6dOi30/JtuuilJ0qZNm3zve98re2/jjTfOO++8M981H3zwQYYMGZIhQ4bk8ssvz5///OesuuqqDftF/ufxxx/PwIEDy4qY0aNH5/7778/999+f0047rVHuW9f48eOzyy675Mknnyybjxs3LkOHDs3QoUNz8cUX5y9/+UvWWGON+a5f0PdIkrFjx2bs2LEZPnx4br311qy88soZOHBg7ftVVVXZe++9c/vtt5ddN2PGjEyaNClvvfVWnnjiifzlL3/Jc88914DfuOkonCDzF04ffphMnJh06VJMHgAAAACAfffdNzfeeGMmT56ce++9N/vss88Cz5s1a1ZtkfH1r389K6+8ctn7VVVV2XLLLTNw4MBsvPHG6dWrV2bMmJG33norN954Yx588MG8+OKL2WuvvRa5Qmlpvfvuu7UlTatWrXLYYYflO9/5Trp27ZqXX34555xzTk477bRsttlmDX7veVVVVWXgwIF5+umnkyRf/epXc8wxx6R///55//33c/XVV+eee+7Ja6+9lu233z4vvfRSOnfuXHv99OnTs9dee2XChAnp0qVLjjzyyGy33Xbp2bNn7Z/nU089lbvvvnu+e1922WW1/4y23nrr/OAHP8haa62VTp065aOPPsrLL7+cBx98MJ9++mmj/hk0JoUTJOnfPymVkurqubM330w22qiwSAAAAADQfM2enXz0UdEpmlaPHkmrhn2KzQ477JCePXtm7NixufnmmxdaOP3tb3/L2LFjk2SB2+898sgj+cxnPjPffKuttsq+++6ba665Joccckgee+yxPPzww9l+++0b9HuccMIJtSuCbrzxxuy9996172222Wb57ne/m2222abRV/ZcfvnltWXTAQcckGuvvTalUilJsummm2bnnXfOz3/+8/zqV7/Km2++mTPPPDPnnntu7fVPPvlk3n///STJzTffXLaCKUm++MUvZu+9987vf//7TJkypey92267LUmy5ZZb5tFHH02bNuX1zA477JAf/ehHGT9+fMN+6SakcIIkHTokffoko0bNnY0YoXACAAAAgKXy0UdJz55Fp2haY8cmq6zSoB/Zpk2bfP/7389FF12UIUOG5KOPPkqPHj3mO2/OdnqdO3fOrrvuOt/7Cyqb5nXwwQfnwgsvzEsvvZR77rmnQQunMWPG1K74GThwYFnZNEeXLl1y5ZVXZsstt2yw+y7IJZdckiRZZZVVcvHFF9eWTfM6/fTTc9ddd+Xf//53/vCHP+SMM85I+/btk9R8lzm+8pWvLPQ+bdq0yYorrlg2m3PtVlttNV/ZNK/u3bsv+ReqMA1bt0Iz5jlOAAAAAEClmbNiaebMmbWrZOY1derU3HPPPUmS3XbbLSussMIiP6+6ujpjxozJf//73wwfPrz2p0+fPkmSf/7znw2a/9FHH01VVVWSmmJrYbbYYot87nOfa9B7z+v999/Pa6+9liT53ve+ly4LeZ5KmzZtanN+/PHHeeGFF2rf6927d+3ra665pl73n3Pt/fffn3HjxtXr2uZC4QT/o3ACAAAAACrNlltumbX+95eXc1Yyzeu+++7LpEmTkix4O705Bg8enIEDB6Zr167p3bt3PvvZz2bDDTes/Rk8eHCSNHgZ8sorr9S+3nzzzRd57hZbbNGg957X8OHDa18vbiXVvO/Pe93WW2+dAQMGJEmOP/74bLHFFjn77LPz5JNPZsaMGYv8zAMPPDBJ8sYbb2TttdfOIYcckltuuSWj5t12q5lTOMH/KJwAAAAAgEo0p0h66qmn8vbbb5e9N6eE6tmzZ3bYYYf5rq2urs4PfvCDDBw4MIMHD87EiRMXea+pU6c2TOj/mfeZRD0Xs81ir169GvTeS5tj1VVXXeB1bdu2zf3335/11lsvSfKPf/wjJ510Urbeeut069Yt3/jGN3LzzTfXruia1yGHHJKTTjopbdq0yaeffpprrrkm++yzT/r165e11147J5xwQkaMGLGsX7NQnuEE/6NwAgAAAIAG0qNHzTONWpIFPFupoey7774544wzUl1dnVtuuSU/+9nPktSUIQ899FCS5Pvf//4Cnw109dVX549//GOSZKONNsrxxx+fLbfcMn369MkKK6yQ1q1bJ0kOOOCA3HDDDamurm6077GgZyYVYVlyrL/++nnllVdy//335/7778/f//73vPHGG5k6dWoeeuihPPTQQ/nd736XP//5z/MVW7/85S9z2GGH5aabbsrDDz+cZ555JlOmTMmbb76Z3/3ud7noooty4YUX5ogjjljWr1gIhRP8z/9WQtZ6991k5sykbdti8gAAAABAs9WqVbLKKkWnWG6ss8462WyzzfLcc8/l5ptvri2c7rjjjtqt3Ba2nd4f/vCHJMnaa6+dp556Kh07dlzgefOu5GlIK620Uu3rDz74IP369VvouR988EGjZEiS7t27L/F9xowZs8Dr5mjdunV222237LbbbkmS0aNH58EHH8wll1yS559/Ps8//3wOP/zw3H333fNdu8Yaa+Skk07KSSedlJkzZ+Yf//hHbrvttlxxxRWZNm1ajjrqqGy55ZbZeOONl/KbFseWevA/dVc4VVUl77xTTBYAAAAAgHnNKZSGDx+el19+Ocnc7fTWWmuthT6X6F//+leSZJdddllo2VRdXZ0XXnihoSMnSTbccMPa1//4xz8Wee7i3l8WG2ywQe3rZ599dpHnDhs2bIHXLUzv3r1z8MEH5+mnn84mm2ySJHnggQcWuz1h27Zts9VWW+X888/PzTffnKTmn8Udd9yx2HtWIoUT/E/37km3buUz2+oBAAAAAJVgr732qt3+7qabbsqoUaPy+OOPJ1n46qYkmTVrVpJk8uTJCz3n3nvvzejRoxsw7Vzbbbddbe7rrrtuoef94x//yPDhwxslQ5Ksttpqtc9euu222zJp0qQFnldVVZVrr702Sc3qrDkF0pJo27ZtvvrVryap+XP/5JNPlvja7bffvvb1uHHjlvi6SqJwgnl4jhMAAAAAUIlWXXXVfO1rX0uS3HLLLbn55ptrn7e0qMLpM5/5TJLk/vvvX+C2eW+++WaOPvroRkhco3fv3tl1112TJPfdd19uu+22+c6ZNGlSDj/88EbLMMec7/nhhx/muOOOW+A5p59+el599dUkyQ9/+MO0b9++9r3HH388b7zxxkI/f8aMGXnssceSJJ07d84q82wreeONN9aWfwsyZMiQ2tf9+/dfgm9TeRROMI+6hdOIEcXkAAAAAACoa06xNHLkyJx99tlJks022yzrrLPOQq854IADkiTvv/9+vvSlL+Xqq6/OsGHD8ve//z2nnXZaNt1004wfP75eK3nq67e//W26dOmSJNlnn31y9NFH59FHH83zzz+fa665JptuumlefPHFbLbZZo2WIUmOOOKIfOlLX0qSXHPNNdl+++1z55135oUXXsjgwYOz55575swzz0xSs03hKaecUnb9ww8/nM9+9rPZdtttc9555+Whhx7KCy+8kCeffDLXXHNNttlmm9qtCQ899NC0adOm9tr9998/ffv2zVFHHZUbb7wxTz/9dF588cU8+OCDOeGEE2r/OXXu3HmRBWIla7P4U6DlsMIJAAAAAKhUe+yxR4488shMnTq1dru2xZUTgwYNyl//+tcMGTIk//3vf3PooYeWvd+xY8dcf/31GTx4cKM9x2nNNdfMfffdl1122SUTJ07MpZdemksvvbTsnFNPPTWlUinPPfdco2RIktatW+eBBx7ILrvskieffDKPPPJIHnnkkfnOW2+99fKXv/wlnTt3nu+92bNn57HHHqtdybQgu+66a20hOK8PPvggl112WS677LIFXte1a9fceuut6devXz2+VeWwwgnmoXACAAAAACpVly5dsvPOO9cet27dOnvttdcir2nbtm0GDx6cCy+8MJtttllWWGGFdOzYMWuvvXaOOOKIvPDCC/nud7/b2NGz7bbb5l//+leOPPLIrLHGGmnXrl169eqVb3/723nwwQdz+umnN3qGJOnevXv+/ve/5/rrr883vvGN9OrVK23btk2PHj2y7bbb5uKLL85LL72UNdZYY75rf/zjH+fOO+/MkUcemS9+8YtZffXV06FDh3To0CFrrrlmvve97+WBBx7IPffck44dO5ZdO3z48Jx7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iybLRHHWWit54425xwonAAAAAACauxa7wmleq6++enbaaadG+/xDDjmktmzabrvtcs8992TYsGH54x//mLXWWiuzZ8/OaaedliuvvLLRMlA5BgwoP1Y4AQAAAADQ3LXYFU6nnnpqNt9882y++ebp1atX3n777fTv37/B7/PII4/k1ltvTZLsvPPOufvuu9O6deskyeabb55ddtklm266ad59992ceOKJ+e53v5uVVlqpwXNQOdZaq/x4xIhicgAAAAAAQENpsSucTj/99AwcOLDRt9b7zW9+kyRp06ZNLr300tqyaY6VV1455557bpLkk08+yVVXXdWoeShe3cLJCicAAAAAAJq7Fls4NYWJEyfm4YcfTpLssMMO6du37wLP22OPPbLiiismSe6+++4my0cx6hZO77+fTJ1aTBYAAAAAAGgICqdG9I9//CMzZsxIknz1q19d6Hnt2rXLF7/4xdprZs6c2ST5KEbdZzglttUDAAAAAKB5a7HPcGoKr776au3rddddd5HnrrvuuhkyZEhmzZqV119/Peuvv/4S32fUqFGLfH/06NFL/Fk0vk6dklVXTcaMmTt7883kc58rLhMAAAAAACwLhVMjmrcIWth2enP069ev9vXIkSPrVTjNey3Nw1przV84AQAAAABAc2VLvUY0ceLE2tedO3de5LmdOnWqfT1p0qRGy0RlqPscJ4UTAAAAAADNmRVOjWjatGm1r9u1a7fIc9u3b1/7eurUqfW6z8iRIxf5/ujRo7PFFlvU6zNpXAonAAAAAACWJwqnRtShQ4fa1zNmzFjkudOnT6993bFjx3rdZ3Hb9VF5BgwoP1Y4AQAAAADQnNlSrxF16dKl9vXitsmbPHly7evFbb9H81d3hdPbbydVVYVEAQAAAACAZaZwakTzrjwaNWrUIs+dd1u8fv36NVomKkPdwmnmzGQx/4oAAAAAAEDFUjg1ovXXX7/29b///e9Fnjvn/TZt2uQzn/lMo+aieKusktRdyGZbPQAAAAAAmiuFUyPafPPN065duyTJY489ttDzZsyYkWeeeab2mrZt2zZJPopTKs2/yknhBAAAAABAc6VwakRdunTJ9ttvnyT529/+ttBt9e66665MmDAhSbL77rs3WT6KpXACAAAAAGB5oXBaBtdee21KpVJKpVJOO+20BZ7z4x//OEkya9asHH300amq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f/lLMVkWYK21km9+s3x27rnJp58WkwcAAAAAgJZL4QQLs+22yec/Xz674IJCoizMmWeWH48fn5x/fiFRAAAAAABowRROsDClUnLcceWzv/41+de/ismzAJtumuyxR/nst79NPvqomDwAAAAAALRMCidYlH32SVZeuXx24YXFZFmIM86o6cbmmDgxOe+84vIAAAAAANDyKJxgUTp2TA4/vHx2ww01e9dViM99rqYXm9eFFyZjxhSTBwAAAACAlkfhBItz1FFJmzZzj6dOTf7wh+LyLMBppyWtW889njo1OfvswuIAAAAAANDCKJxgcVZbLfnud8tnl1ySzJpVTJ4FWHvt5OCDy2eXX568+24xeQAAAAAAaFkUTrAkBg0qPx45Mrn77mKyLMQppyTt2s09njEjOeus4vIAAAAAANByKJxgSWy5Zc3PvC64oJgsC7H66vM/burqq5M33igmDwAAAAAALYfCCZZU3VVOTz6ZPP98MVkW4qSTko4d5x5XVSWnn15cHgAAAAAAWgaFEyyp73yn5nlO86qwVU6rrpoce2z57Kabkn/9q5g8AAAAAAC0DAonWFJt2yZHHVU+u/XWZMyYYvIsxE9+knTpMve4ujo59dTi8gAAAAAAsPxTOEF9HHZY0r793OOZM5PLLy8uzwL06JH86Efls7vuqrjd/wAAAAAAWI4onKA+Vlkl2Xff8tlllyXTpxeTZyH+7/+S7t3LZ6ecUkwWAAAAAACWfwonqK9Bg8qPx45N/vSnYrIsRNeuNVvrzesvf0mefLKYPAAAAAAALN8UTlBfn/98st125bPzz695WFIFOeaYpFev8tnJJ1dcTAAAAAAAlgMKJ1gadVc5vfhi8sQTxWRZiE6dkpNOKp8NHZo88kghcQAAAAAAWI4pnGBpDByY9O9fPrvggmKyLMLhhyf9+pXPfv5zq5wAAAAAAGhYCidYGq1bJ8ceWz67++7knXeKybMQ7dsnp5xSPnv22WTw4GLyAAAAAACwfFI4wdI65JCkc+e5x7NnJ5dcUlyehTjooGSttcpnJ59cExcAAAAAABqCwgmWVteuNW3OvP7wh2Ty5ELiLEzbtslpp5XP/vnP5M47C4kDAAAAAMBySOEEy6LutnqffJLccEMhURZl772T9dcvn516alJVVUweAAAAAACWLwonWBbrrJN861vlswsvTKqri8mzEK1bJ2eeWT7797+Tm24qJg8AAAAAAMsXhRMsq0GDyo9fey3561+LybIIu++ebLJJ+ey005IZMwqJAwAAAADAckThBMtqxx2T9dYrn11wQTFZFqFUSs46q3z21lvJ1VcXkwcAAAAAgOWHwgmWVamUHHdc+ezPf07++99i8izCN76RbLVV+ezMM5OpU4vJAwAAAADA8kHhBA1h//2TlVYqn110UTFZFqFUSn75y/LZ++8nl19eTB4AAAAAAJYPCidoCJ06JT/8YfnsmmuSTz4pJM6ibLttsv325bOzz04mTSokDgAAAAAAywGFEzSUo49OWreeezx5csU+IKnus5w+/DC58MJisgAAAAAA0PwpnKChrL56svvu5bOLLkqqqorJswhf/GIycGD57LzzKnJBFgAAAAAAzYDCCRrSoEHlx2+/ndx/fyFRFufMM8uPP/kk+e1vC4kCAAAAAEAzp3CChvTlLyebbFI+u+CCYrIsxkYbJd/9bvns/PNrttcDAAAAAID6UDhBQyqV5l/lNHRo8vLLhcRZnNNPT1rN81+BSZOSc88tLg8AAAAAAM2Twgka2ve/n/TqVT6r0FVO662X7Ldf+eySS5L33y8mDwAAAAAAzZPCCRpa+/bJEUeUz266qWL3qvvFL5I2beYeT5uW/PKXxeUBAAAAAKD5UThBYzjiiKRt27nH06cnV15ZXJ5FGDAgOfTQ8tkf/pC8/XYhcQAAAAAAaIYUTtAYVl012Wuv8tmllyYzZxaTZzFOPrlmYdYcM2cmZ5xRXB4AAAAAAJoXhRM0lkGDyo/ffz+5445isixG377JUUeVz667LvnPf4rJAwAAAABA86Jwgsay6abJ1luXzy64oJgsS+CnP006dZp7PHt2ctpphcUBAAAAAKAZUThBY6q7yunZZ2t+KlDPnvPHvfXW5OWXi8kDAAAAAEDzoXCCxrTbbsnqq5fPKniV049/nHTtWj479dRisgAAAAAA0HwonKAxtWmTHH10+ez225P33ismz2KstFJN6TSve+9Nhg0rJg8AAAAAAM2Dwgka2w9+kHTsOPd41qzk0kuLy7MYgwYlK69cPjvllGKyAAAAAADQPCicoLF1754ccED57IorkqlTi8mzGF26JD/9aflsyJDk738vJg8AAAAAAJVP4QRN4bjjyo8/+ii5+eZisiyBo45Kevcun518clJdXUweAAAAAAAqm8IJmsL66yc77lg+u+CCim1wOnasKZjm9fjjNSudAAAAAACgLoUTNJVBg8qPX3klGTq0kChL4gc/SNZYo3xmlRMAAAAAAAuicIKm8s1vJp/5TPnsgguKybIE2rVLfvGL8tlzzyX33ltMHgAAAAAAKpfCCZpKq1bJsceWz+67Lxkxopg8S2D//ZN11imfnXJKUlVVTB4AAAAAACqTwgma0kEHJSuuOPe4ujq5+OLC4ixOmzbJ6aeXz4YPT267rZg8AAAAAABUJoUTNKUuXZJDDy2f/fGPycSJxeRZAt/7XrLhhuWzX/wimTWrmDwAAAAAAFQehRM0tWOOSUqluccTJiTXXVdcnsVo1So588zy2euvJ9dfX0weAAAAAAAqj8IJmtqAAckuu5TPLrwwmT27mDxLYJddks03L5+dfnoyfXoxeQAAAAAAqCwKJyjCoEHlx6+/njz4YDFZlkCplJx1Vvns3XeTq64qJg8AAAAAAJVF4QRF2Hbb5POfL5+df34RSZbYjjsmX/lK+eyss5IpU4rJAwAAAABA5VA4QRFKpeS448pnf/1r8uqrxeRZAgta5TRmTHLppcXkAQAAAACgciicoCj77JP06FE+u/DCYrIsoW22Sb7+9fLZOeckEyYUkwcAAAAAgMqgcIKidOyYHH54+ez665Px44vJs4TOPLP8+KOPkgsuKCYLAAAAAACVQeEERTrqqKRNm7nHU6cmV11VXJ4lsPnmyW67lc9+85uK78kAAAAAAGhECicoUp8+yXe+Uz67+OJk1qxi8iyhM86oeabTHBMmJOedV1weAAAAAACKpXCCog0aVH48cmRyzz2FRFlSG26Y7LVX+ezCC5MPPigmDwAAAAAAxVI4QdG++MVkyy3LZ83goUinnZa0bj33eMqU5OyzC4sDAAAAAECBFE5QCequcnriieSFF4rJsoTWWSc58MDy2WWX1SzQAgAAAACgZVE4QSX4zneS1VYrnzWDVU6nnJK0bTv3eMaM5KyzissDAAAAAEAxFE5QCdq2TY46qnx2660V/1CkNddMDjusfHb11cmbbxYSBwAAAACAgiicoFIcdljSvv3c4xkzkssvLy7PEjrppKRDh7nHs2Ylp59eXB4AAAAAAJqewgkqxSqrJPvuWz677LJk+vRi8iyh1VZLjjmmfHbjjcmrrxaTBwAAAACApqdwgkoyaFD58QcfJH/6UzFZ6uHEE5POneceV1cnv/hFcXkAAAAAAGhaCieoJJ//fLLttuWzCy6oaXAq2MorJ//3f+WzO+5IXnyxmDwAAAAAADQthRNUmrqrnF54IXnyyWKy1MOPfpSstFL57JRTiskCAAAAAEDTUjhBpdl556R///LZBRcUk6UeunVL/t//K58NHpw8/XQhcQAAAAAAaEIKJ6g0rVsnxxxTPrv77uTdd4vJUw/HHZf07Fk+O/nkYrIAAAAAANB0FE5QiQ45JOnUae5xVVVyySXF5VlCnTolP/tZ+eyRR2p+AAAAAABYfimcoBJ165YcfHD57A9/SCZPLiROfRxxRNKnT/ns5JOT6upi8gAAAAAA0PgUTlCpjj22/Pjjj5MbbywmSz106JCcckr57Omnkz//uZg8AAAAAAA0PoUTVKp11km+9a3y2YUXNoulQocckgwYUD475ZRk9uxi8gAAAAAA0LgUTlDJBg0qP3711eRvfysmSz20bZv84hflsxdfTO66q5g8AAAAAAA0LoUTVLIdd0zWW698dsEFxWSpp333TdZdt3x26qlJVVUxeQAAAAAAaDwKJ6hkpVJy3HHls8GDk9dfLyZPPbRunZxxRvnstdeSm28uJg8AAAAAAI1H4QSVbv/9k27dymcXXVRIlPrac89ko43KZ6edlsycWUQaAAAAAAAai8IJKl2nTskPf1g+u+aa5NNPi8lTD61aJWeeWT4bMaImPgAAAAAAyw+FEzQHRx9d097MMWlScvXVxeWph29/O/niF8tnZ56ZTJtWTB4AAAAAABqewgmagzXWSHbfvXx20UVJVVUxeeqhVEp++cvy2ahRyRVXFJMHAAAAAICGp3CC5mLQoPLjt95KHnigmCz19LWvJdttVz771a+SyZOLyQMAAAAAQMNSOEFzsfXWySablM8uuKCYLEvhrLPKj8eOrVmkBQAAAABA86dwguaiVJp/ldOjjyYvv1xMnnraaqvkW98qn/3618knnxQSBwAAAACABqRwgubk+99PevUqn114YTFZlsKZZ5Yff/xx8vvfF5MFAAAAAICGo3CC5qR9++SII8pnN92UjBtXTJ562mSTZM89y2e/+12ziQ8AAAAAwEIonKC5OeKIpG3bucfTpiVXXllcnno644ya3QHnmDSpZms9AAAAAACaL4UTNDerrprstVf57NJLk5kzi8lTT+uvn+y7b/ns4ouT0aOLyQMAAAAAwLJTOEFzNGhQ+fF77yV33llMlqVw2mlJ69Zzj6dOTX71q8LiAAAAAACwjBRO0Bxtumny5S+Xz37zm6S6upg89bTWWskhh5TPrrgiGTGimDwAAAAAACwbhRM0V3VXOT3/fHL33cVkWQqnnJK0azf3eObM5Hvfq3kkFQAAAAAAzYvCCZqr3XdP1lmnfPbznyezZhWTp5769UuOPLJ89vzzyTHHFJMHAAAAAIClp3CC5qpNm+Sss8pn//53cv31xeRZCmecMX9n9sc/Jn/4QzF5AAAAAABYOgonaM723LPmeU7z+sUvms2+dCuumNx1V9KpU/n8mGOSYcOKyQQAAAAAQP0pnKA5a9UqOfvs8tmoUckllxSTZyl87nPJ1VeXz2bMSL7zneTDD4vJBAAAAABA/Sickrzzzjs54YQTsu6666ZTp07p3r17Nt9885x33nmZMmVKg9zj7bffzoknnphNN9003bp1S9u2bdO9e/dstdVWOeOMMzJ27NgGuQ8t0A47JF/7WvnsV79KPv20mDxL4XvfS370o/LZyJHJXns1m0dSAQAAAAC0aKXq6urqokMU6f77789+++2XCRMmLPD9ddZZJ4MHD87aa6+91Pe44YYbcvjhh2fq1KkLPad79+659dZbs+OOOy71fRZm1KhR6devX5Jk5MiR6du3b4Pfg4ING5ZsuWX57OSTkzPPLCbPUpg1q6Y7e+yx8vmJJybnnFNMJgAAAACA5VFj9AYteoXTiy++mO9///uZMGFCOnfunF/+8pd56qmn8vDDD+eHP/xhkuS///1vvv3tb2fixIlLdY8nn3wyBx10UKZOnZpWrVrl4IMPzj333JNhw4bljjvuyM4775wkGT9+fHbdddeMGDGiwb4fLcgWWyR77FE++93vkg8+KCbPUmjTJvnTn5I+fcrn555b85wnAAAAAAAqV4sunAYNGpSpU6emTZs2GTJkSE466aR86Utfyte+9rVceeWV+fWvf52kpnT67W9/u1T3OPvsszN79uwkyUUXXZSrr746u+66azbffPPsueeeue+++/Kj/+0lNnXq1Pzud79rmC9Hy3PWWTXPdJpjypSaWTPSq1dyxx1J27bl8wMPTP7972IyAQAAAACweC22cBo2bFgef/zxJMmhhx6aL33pS/Odc8IJJ2S99dZLklxwwQWZOXNmve/z1FNPJUl69OiRo446aoHnnHrqqbWvn3766XrfA5Ik662XHHRQ+eyKK5Jmtmrui19MLrigfDZpUrL77slSLjQEAAAAAKCRtdjC6Z577ql9ffDBBy/wnFatWuWAAw5IknzyySd59NFH632fGTNmJEn69++/0HO6du2alVdeuex8WCq/+EXSvv3c45kza2bNzBFHJP/71av1738nBx+ctOynzgEAAAAAVKYWWzg98cQTSZJOnTpl0003Xeh5X/3qV2tfP/nkk/W+z2c/+9kkyVtvvbXQcyZMmJBx48aVnQ9LZfXVk6OPLp/ddFPy8svF5FlKpVJy+eXJRhuVz++8M/nNbwqJBAAAAADAIrTYwum1115Lkqy99tpp06bNQs9bd91157umPo444ogkyUcffZTLL798geeceeaZ851fH6NGjVrkz+jRo+v9mTRjJ52UrLji3OPq6uTnPy8uz1Lq2DG5665kpZXK5z/9afLII8VkAgAAAABgwRbetCzHpk2bVruiqG/fvos8d6WVVkqnTp0yefLkjBw5st73OuSQQ/LEE0/k+uuvz9FHH53nn38+u+yyS3r37p133303N9xwQ+32fj//+c+zww471Pse/fr1q/c1LMd69Ej+3/9LTjll7uyBB5Innki23rq4XEuhf//k5puTb31r7lZ6s2cn3/9+8sILiX/1AQAAAAAqQ4tc4TRx4sTa1507d17s+Z06dUqSTJo0qd73at26da677rrcfvvt+cIXvpCrrroqu+yySzbffPPsueeeueeee7Lddtvlr3/9a84666x6fz4s0PHHJz17ls9++tNm+QCkb3wjOf308tm4ccl3vpNMn15MJgAAAAAAylXkCqcPPvggDzzwQMaNG5f+/ftn4MCBWWGFFRrs86dNm1b7ul27dos9v3379kmSqVOnLtX9XnvttVx//fV55ZVXFvj+008/nT/+8Y9Zb7310qdPn3p//uJWXo0ePTpbbLFFvT+XZqxz55oVTsceO3f25JPJ4MHJwIHF5VpKP/958o9/JPffP3c2bFhy3HHJFVcUlwsAAAAAgBpNvsLptddey/e+9718//vfzyeffDLf+/fdd1/WWmutHHbYYTnppJOy9957Z7311stLL73UYBk6dOhQ+3rGjBmLPX/6/5ZRdOzYsd73evzxx/OlL30p999/f/r06ZMbbrghY8aMyYwZMzJy5MhccsklWWGFFXLrrbdmiy22yL/+9a9636Nv376L/Ondu3e9P5PlwGGHJWuuWT772c+SqqpC4iyLVq2S669P1l67fH7llcnVVxeTCQAAAACAuZq8cLrnnntyxx135P3330+3bt3K3hs7dmz222+/TJkyJdXV1bU/I0eOzM4777xUW9otSJcuXWpfL8lnTp48OcmSbb83r+nTp2fvvffOp59+mlVXXTXPPPNM9ttvv/Tq1Stt27ZN3759c9RRR+Xvf/97OnTokPfffz8HHnhg/b4MLEy7dsmZZ5bPhg9PbrmlmDzLqFu35K67krqLHY86Knn++UIiAQAAAADwP01eOD388MMplUoZuIBtvS699NJMmjQpbdq0ye9+97v885//zK9//eu0atUq77//fv7whz80SIYOHTqkR48eSZJRo0Yt8tyPP/64tnDq169fve7z4IMP5r333kuSHHvssVl11VUXeN7nPve57LfffkmS559/Pv/85z/rdR9YqL33TjbcsHx2yinJEqzsq0QbbphcdVX5bPr0ZM89k48+KiYTAAAAAAAFFE7vvvtukmTjjTee770777wzpVIpBxxwQI4//vhsuOGG+fGPf5xDDz001dXVue+++xosx/rrr58keeONNzJr1qyFnvfvf/+79vV6661Xr3u89tprta832WSTRZ676aabLvCesExat05+9avy2dtv1+xF10ztvXcyaFD57J13aubNcLdAAAAAAIDlQpMXTmPHjk2S9OzZs2w+bty42ucX7bPPPmXv7bLLLkmSV199tcFybL311klqtst7fhH7cT322GO1r7/85S/X6x5t2rSpfb2oUitJZs6cucDrYJl9+9tJ3X93zzwzaaAtKotw3nnJ/36Fa/31r8mppxaTBwAAAACgpWvywmnq1KlJkmnTppXNn3jiiSRJu3btasugOXr37p0k+eSTTxosx2677Vb7+pprrlngObNnz87111+fJOnWrVu22267et2jf//+ta8ff/zxRZ47b7E173WwzEql5Jxzymdjxybnn19InIbQtm1y221J3V0qf/Wr5N57i8kEAAAAANCSNXnh1L179yRzt9ab4+GHH06SbLbZZmnXrl3Ze3NWB3Xu3LnBcmyxxRbZZpttkiR//OMf8/TTT893zm9/+9vabfEGDRqUtm3blr0/dOjQlEqllEqlHHTQQfNdv/3222eFFVZIklx22WV55ZVXFpjlL3/5S+6+++4kSZ8+fbLRRhst7deCBdt666Tuc9POOy8ZN66YPA2gd+/kjjuSugsCDzgg+e9/i8kEAAAAANBSNXnh9IUvfCFJcvPNN9fOpk6dmttvvz2lUilf+9rX5rvmnXfeSZL06tWrQbNccMEF6dixY2bNmpWddtopZ599dp555pk8+uijOfzww/OTn/wkSbLOOuvkhBNOqPfnd+vWLT/96U+TJBMnTsxWW22Vk046KY8++mheeumlPPTQQznqqKOyyy67ZPbs2UmSc845J61aNfk/FlqCX/6yZrXTHBMmJGefXVyeBvDlLye/+135bMKEZPfdm/WOgQAAAAAAzU6TPyxor732ypAhQ3L//fdnr732ytZbb50//elPGTt2bFq1apW99957vmueffbZJMkaa6zRoFk23njj/OlPf8p+++2XCRMm5KSTTprvnHXWWSeDBw9Oly5dluoeJ598csaPH58LLrggkyZNytlnn52zF/CX/G3bts2vfvWr7Lfffkt1H1isz38+2Xff5MYb584uuSQZNChZffXici2jY45Jnn02uemmubNXX00OPTS59dbyjg0AAAAAgMbR5EtpDjjggGy99daprq7O7bffnkGDBuWpp55Kkhx88MFZd91157vmrrvuSqlUylZbbdXgeXbeeee8/PLL+b//+7+ss846WWGFFdKtW7dsttlmOffcc/Piiy9m7bXXXurPL5VK+f3vf59//OMfOeKII7LBBhukS5cuad26dbp27ZpNN900P/rRjzJ8+PD8+Mc/bsBvBgtw+uk1D0CaY/r0mlkzViolV15Z06fN67bbkt//vphMAAAAAAAtTam6urq6qW86efLk/OIXv8jtt9+eMWPGpHfv3jnwwANzyimnpE2dB7I88MAD2WWXXVIqlTJs2LBsuummTR232Rs1alT69euXJBk5cmT69u1bcCIKdeyxycUXzz1u1SoZPjxZb73iMjWAN99MNtss+eSTubPWrZO//S3ZdtuiUgEAAAAAVJ7G6A0KKZzq4+OPP86ECROSNPyWei2FwokyH3yQrLVWMnny3NkeeyR33llcpgYyeHAycGD5rGfP5IUXkj59iskEAAAAAFBpGqM3aPIt9eprpZVWyhprrKFsgobSq1fyf/9XPrvrrmTYsGLyNKBvfzv5xS/KZ2PHJt/5TjJjRjGZAAAAAABagoovnIBG8OMfJ927l89++tOkshc8LpFTT02+9a3y2TPPzN+xAQAAAADQcJq8cJo5c2ZeffXVvPrqq5k+ffp870+bNi0nnHBC+vXrl44dO2b99dfPRRdd1NQxYfnWtWty0knls0cfrXngUTPXqlVy443JgAHl80svTa6/vphMAAAAAADLuyYvnO6+++5suOGG+epXv7rA93ffffecf/75ee+99zJ9+vT8+9//zvHHH59jjjmmiZPCcu7oo5O6+3L+7GfJ7NnF5GlAK61U80iqDh3K54cfnrz4YjGZAAAAAACWZ01eOD300EOprq7Obrvtlvbt25e9N3jw4Dz00ENJkr59+2b33XdPnz59Ul1dncsuuyxPPfVUU8eF5VeHDsnpp5fPnn++pqlZDmy0UXLlleWzadOSPfdMxo8vJBIAAAAAwHKryQunF154IaVSaYErnK6++uokyTrrrJN//etfufPOOzN8+PCst956SZKrrrqqSbPCcu+AA5J11y2f/fznycyZxeRpYPvvX7OQa15vvZXsu29SVVVMJgAAAACA5VGTF05jx45Nkqy99tpl89mzZ+fhhx9OqVTKsccemy5duiRJunbtmmOOOSbV1dV5+umnmzouLN/atEl++cvy2euvJ9dcU0yeRvC73yVbbVU+e/DB+Rd3AQAAAACw9Jq8cBo3blySpGPHjmXzl156KRMmTEiSfPvb3y57b4MNNkiSjBw5sgkSQguz++7J5puXz04/PZkypZg8Daxdu+T225NevcrnZ56Z3H9/MZkAAAAAAJY3TV44zXlu05ziaY6///3vSWqe3bTGGmuUvTdntVOVPbCg4ZVKyTnnlM/efz+5+OJi8jSC1VZLbrstad26fL7//skbbxSTCQAAAABgedLkhdOcMunZZ58tm99///0plUr5yle+Mt8148ePT5KsssoqjR8QWqKvfS3Zccfy2dlnJx9/XEyeRvCVryS/+U357NNPkz32SCZPLiYTAAAAAMDyoskLp+222y7V1dW56KKL8tprryVJ7rvvvgwdOjRJ8q1vfWu+a4YPH54k6d27d5PlhBbnV78qP/7kk+S88wqJ0lgGDUr22qt89soryWGHJdXVxWQCAAAAAFgeNHnhdOyxx6Zdu3YZO3ZsNthgg6y88srZfffdU11dnT59+mTPPfec75ohQ4akVCrl85//fFPHhZZjs82S7363fHb++cno0YXEaQylUnLVVcn/HgtX6+abk4suKiYTAAAAAMDyoMkLp8985jO54YYbssIKK6S6ujrjx49PdXV1unXrlltuuSXt2rUrO3/MmDH561//miT52te+1tRxoWU566zyBx1NnZqceWZxeRpBp07JXXclK65YPj/hhOSJJ4rJBAAAAADQ3JWqq4vZSGrs2LEZPHhwxowZk969e2eXXXZJ9+7d5ztvyJAhueWWW5Ik559/frp27drUUZu9UaNGpV+/fkmSkSNHpm/fvgUnoqIdfnhy5ZVzj9u0SV57LVl77eIyNYL77kt23bV8tuqqyQsvJHbvBAAAAACWZ43RGxRWONF0FE7Uy3vv1ZRL06bNne29d82+c8uZk09OfvnL8tmXv5w88khSZ7ElAAAAAMByozF6gybfUg+ocH36JMcdVz675ZbkxReLydOITj89+frXy2dPPpn8+MfF5AEAAAAAaK4qYoXTBx98kOHDh2f8+PFJku7du2eDDTZIr169Ck62fLDCiXobPz4ZMCD59NO5s298I/nLX4rL1Eg++ijZbLPk7bfL5zfckOy3XyGRAAAAAAAa1XK1wqm6ujpXXHFFNtxww6y22mrZaaedstdee2WvvfbKTjvtlNVWWy0bbrhhrrzyylRAJwYtS/fuyYknls8efDAZOrSQOI2pR4/kzjuTDh3K54cdlvzzn8VkAgAAAABobgopnD7++ON85StfyVFHHZVXX3011dXVC/x59dVXc+SRR+YrX/lKPvnkkyKiQst13HHJqquWz372s2Q5LIA32SS57LLy2dSpyR57JB9/XEwmAAAAAIDmpMkLp+rq6uy666558sknU11dne7du+fII4/MtddemwcffDAPPvhgrr322hx11FHp0aNHqqur89RTT2XXXXdt6qjQsnXqlJx6avnsmWeS++4rJk8jO+ig5IgjymcjRiT775/Mnl1IJAAAAACAZqPJn+F00003Zf/990+pVMo+++yTSy+9NF26dFnguZMmTcrRRx+dG264IaVSKTfeeGP23nvvpoy7XPAMJ5bazJnJeuslb745d7b++snLLyetWxeXq5FMn5589avJs8+Wz08/ff7uDQAAAACguVounuF08803J0m++tWv5oYbblho2ZQknTt3znXXXZevfvWrqa6uzo033thUMYEkads2OfPM8tmrrybL6e9i+/bJHXckPXuWz087LfnLXwqJBAAAAADQLDR54fTCCy+kVCrlmGOOWeJrjj322CTJiy++2FixgIX5/veTjTYqn516as1yoOVQ377Jn/5UvoCrujrZZ5+aLfYAAAAAAJhfkxdO48ePT5L0799/ia+Zc+6ca4Em1KpVcvbZ5bN3300uv7yYPE1g222Tc88tn33ySbLHHsmUKUUkAgAAAACobE1eOHXt2jVJ8v777y/xNaNHj06SrLjiio2SCViMr3+95uFG8zrrrGTChGLyNIEf/Sj57nfLZ//8Z3LEETUrngAAAAAAmKvJC6cNNtggSXLNNdcs8TVzzp1zLdDESqX5VzmNG5f87nfF5GkCpVLyxz8m661XPr/hhuTSS4vJBAAAAABQqZq8cPrOd76T6urq3H333TnttNNSvZilAmeeeWbuvPPOlEqlfLfucgOg6XzpS8muu5bPfvvbZOzYYvI0gS5dkrvvrvnfeR1/fPLUU4VEAgAAAACoSKXqxTU+DWzmzJn5/Oc/n//85z8plUr53Oc+l4MOOihbbrllevbsmVKplA8++CDPPvtsrrvuugwfPjzV1dVZb7318s9//jNt2rRpyrjLhVGjRqVfv35JkpEjR6Zv374FJ6LZ+te/kg03LN9TbtCg5PzzC4vUFO6+u+b5TfPq3Tt54YVk1VWLyQQAAAAAsLQaozdo8sIpSd5+++1sv/32eeutt1IqlRZ5bnV1dQYMGJCHH344a6yxRhMlXL4onGhQBx2UXHfd3ON27ZL//CdZc82iEjWJn/0sOeec8tk22yQPP5y0bVtMJgAAAACApdEYvUGTb6mXJGuuuWZefvnlnHDCCenatWuqq6sX+NO1a9f8+Mc/zksvvaRsgkpx2mk1JdMcM2bUzJZzZ52V7LBD+ezxx5Of/KSYPAAAAAAAlaSQFU7zmjFjRp5//vkMHz4848ePT5J07949G2ywQTbddNO0a9cuo0aNygsvvJAk2WWXXYqM2yxZ4USDO/745IIL5h6XSsnLLycbbFBYpKYwblyy6abJu++Wz2+5Jdlrr2IyAQAAAADU13KzpV59XXfddTn44IPTqlWrzJo1q+g4zY7CiQY3dmyy1lrJpElzZ7vumtxzT2GRmspzzyVbb51Mnz53tsIKybPPLvd9GwAAAACwnFhuttRbWs2gG4OWoWfP5IQTymf33ps8/XQxeZrQZpsll1xSPpsyJdljj+TTT4vJBAAAAABQtGZVOAEV5IQTkpVXLp/99KdJCyiGDz00+eEPy2evv55873s15RMAAAAAQEujcAKWTpcuycknl8/+/vfkwQeLydPELroo2Xzz8tmQIck3v5lMmFBMJgAAAACAoiicgKV3xBHJ6quXz372s2T27GLyNKH27ZM77ph/kdff/5587WvJuHHF5AIAAAAAKILCCVh67dsnZ5xRPvvnP5M//amYPE1s9dWTBx5IunUrnz//fPKVryTvvVdILAAAAACAJqdwApbNfvsl669fPjv55GTGjGLyNLEtt0yGDk169iyfv/Zass02yYgRhcQCAAAAAGhSCidg2bRunfzqV+WzESOSP/6xmDwF+MIXkscfT/r1K5+/9Vay9dbJ8OHF5AIAAAAAaCoKJ2DZ7bJL8sUvls/OOCOZPLmYPAVYZ53kiSdq/ndeo0cnX/1qMmxYMbkAAAAAAJpCm8b88DPqPttlKb300ksN8jlAIymVknPOSbbddu5szJjkwguTn/2ssFhNbfXVa1Y6ff3rybz/2Ro/Ptl+++T++8v/iAAAAAAAlhel6urq6sb68FatWqVUKjXIZ1VXV6dUKqWqqqpBPq8lGTVqVPr9b6+vkSNHpm/fvgUnYrn1zW8mDz4497hr15rt9bp3Ly5TAT75JPn2t5Onniqft2+f3HFHMnBgIbEAAAAAAJI0Tm/Q6FvqVVdXN8gP0AzUfZbTp58m555bTJYCdeuWDBmS7LRT+Xz69GT33ZNbbikkFgAAAABAo2nULfUeffTRxvx4oNJsvHGy997ljcqFFybHHZf06VNcrgJ06pTcd1+yzz7JXXfNnc+aley7bzJhQnL44cXlAwAAAABoSI26pR6VwZZ6NKk33kjWW6+mWZnjhz9MrryyuEwFmjWr5utfe+387517bvKTnzR5JAAAAACghWuWW+oBLczaa9c0LPO6+urkP/8pJk/B2rRJ/vjHmkVedZ14YnLSSYnaHwAAAABo7hROQMM75ZSkY8e5x1VVNbMWqlWr5Pzzk1NPnf+9s89OjjkmmT27yWMBAAAAADQYhRPQ8Hr3To4/vnx2++3Jc88VEqcSlErJ6acnv/3t/O9demly4IHJzJlNnwsAAAAAoCEonP4/e/cdJVWR92H86ZkhZwQEBERFgpIkKaIgCIZVzFkxrlnXNcc1rK9pze6uaVVUzK6KWRElGQmCoBJVEJQskuNMv3/UjjPN5Ga6e8LzOaeOQ1X1vb9GYOB+u6okJcZVV0GDBrF9112XmlrKkMsugyeeCKuecnvuOTjmGNiwITV1SZIkSZIkSdK2MHCSlBj168M118T2ffQRfPxxSsopS846C156CapUie1/6y045BBYsyY1dUmSJEmSJElSvAycJCXORRdB8+axfddeC9FoauopQ449Ft58M/aoK4BPPoGBA+G331JTlyRJkiRJkiTFw8BJUuLUrAk33RTbN2ECvPFGauopYw4+GD78EOrWje3/6ivYbz9YtCglZUmSJEmSJElSiRk4SUqsM86AXXeN7bv+etiyJTX1lDH77gujRkGjRrH906bBPvvA3LkpKUuSJEmSJEmSSsTASVJiVakCt90W2zdjBjzzTGrqKYO6dYOxY2GHHWL7f/ghBFIzZqSmLkmSJEmSJEkqLgMnSYl39NHQvXts3803w/r1KSmnLOrQAT79FHbZJbZ/wYIQOn39dWrqkiRJkiRJkqTiMHCSlHhpaXDHHbF9CxbAww+npp4yqnVrGDcOOnaM7V+2DPr3D4GUJEmSJEmSJJVFBk6SkmPgQBgwILbv9tth5crU1FNGNWsGY8ZAr16x/atWwQEHwAcfpKYuSZIkSZIkSSqMgZOk5IhE8q5y+u03uOee1NRThjVsCCNH5s3n1q+Hww6DV19NTV2SJEmSJEmSVBADJ0nJ06sXHHVUbN9998HixamppwyrUwfefRcGD47t37wZTjgBnnoqNXVJkiRJkiRJUn4MnCQl1//9XzjTKdu6daFPeVSvDq+9BiefHNuflQVnnQUPPJCSsiRJkiRJkiQpDwMnScnVoQOcfnps32OPwY8/pqScsq5KFXj2WTj//Lxjl14KN98M0WjSy5IkSZIkSZKkGAZOkpLv5puhWrWcH2/eDNdeC2vXpqyksiwtDf79b7jmmrxjt9wSgqesrOTXJUmSJEmSJEnZDJwkJV/LlnDRRbF9r7wCdetCp05w5pnw8MMwYQJs3JiaGsuYSATuuCO0rT34IPz5z7BlS/LrkiRJkiRJkiSASDTqZkwV3YIFC2jZsiUA8+fPp0WLFimuSAKWL4edd4ZVqwqfV6UKdO4MPXuG1qMH7LYbZGQkp84y6NFH4YIL8m6ld/TR8PzzsYvHJEmSJEmSJGlricgNKu8TW0mptd12cN11+e8Tl9vmzTBpUmiPPhr6ataEPfYI4VN2ENWmTdh7rhI477ywGOzUUyEzM6f/tddg9Wp4/XWoVSt19UmSJEmSJEmqfAycJKXOlVeGZTovvQTffhubnhRm3Tr47LPQstWrB92756yC6tkTWrUKe9FVQCedBHXqwLHHxu46OGIEHHggvPMO1K+fsvIkSZIkSZIkVTJuqVcJuKWeyoV162DKFJg4MZzdNGECzJy5bdds3Dh2FVTPnrD99qVSblkxahQcdhisWRPb37UrfPghNGmSkrIkSZIkSZIklWGJyA0MnCoBAyeVW6tWha30JkzICaLmzt22a7ZoEbsKqkcPaNCgVMpNlfHj4aCDYMWK2P527eCjj+B/v/0lSZIkSZIkCTBwUpwMnFShLF2aE0Jlt0WLtu2au+ySswKqRw/o1g1q1y6depPk229h0KC8PxWtWsHIkbDrrqmpS5IkSZIkSVLZY+CkuBg4qcL75ZfYVVATJ8Jvv8V/vbQ06NAhdju+Ll2gWrXSqzkBfvgBBg7Muwhs++3D2U6dO6ekLEmSJEmSJElljIGT4mLgpEonGoWffspZATVxYlgVtfVBRyVRpQp06hS7Emr33SEjo/TqLgW//BJWOk2fHttfvz68/z7stVdKypIkSZIkSZJUhhg4KS4GThKQmQkzZ+asgpowAaZMgY0b479mjRqwxx4hfOrfHw47LKyOSrGlS8OZTl9/HdtfqxYMHx5WQUmSJEmSJEmqvAycFBcDJ6kAmzeHw49yb8c3bVoIp+LRrx+89RbUrVu6dcZh5UoYPBjGjYvtr1oVXn4ZjjgiJWVJkiRJkiRJKgMMnBQXAyepBNavh2++id2Ob8aMsE1fcfTsCR98AA0bJrbOYli3Do45Jmyll1t6OgwdCkOGpKYuSZIkSZIkSamViNygbB0+IkmpVqNGOOgo92FHq1aF/emyV0FNnAg//pj/6ydMgAEDYMQIaNIkOTUXoGbNsIXekCHwyis5/ZmZcOqp4W1deGHKypMkSZIkSZJUgRg4SVJR6taF/fYLLdvy5SF4mjgR/vlPWLw4Z+ybb8LckSOhefMkFxuralV44YXwFp54InbsoovC1nvXXguRSGrqkyRJkiRJklQxpP50e0kqj7bbDg48EK6/HsaOha2XnE6fDn37wrx5qakvl/R0ePxxuPzyvGPXXw9XX138HQMlSZIkSZIkKT8GTpK0rdq2DaFT69ax/T/8EEKnOXNSUlZukQjcfTfcemvesbvvhvPOC1vtSZIkSZIkSVI8DJwkqTTstBOMGxfCp9x+/jmETtOnp6auXCIRuOEGeOihvGOPPw4nnwybNye/LkmSJEmSJEnln4GTJJWWFi3CSqeOHWP7Fy6Efv3C2U5lwMUXw9NPQ9pW3wFefhmOOQY2bkxJWZIkSZIkSZLKMQMnSSpN228Po0ZBt26x/UuXwn77wfjxKSlra6edBq++ClWrxva/9RYcdhisW5eauiRJkiRJkiSVTwZOklTaGjWCjz+G3r1j+3//HQYOhE8/TUlZWzvqKHjnHahZM7Z/xAg45BBYvTo1dUmSJEmSJEkqfwycJCkR6tcPyc1++8X2r14NBx4II0emoqo8Bg2CDz+EOnVi+0ePDmWuXJmSsiRJkiRJkiSVMwZOkpQotWvDu++G5Ca3devg0EPDWBmwzz4h/6pfP7b/iy9g//1h+fKUlCVJkiRJkiSpHDFwkqREqlkT3nwTDj88tn/jRjjySHjttdTUtZVevcLRU40axfZPmgT9+8PixampS5IkSZIkSVL5YOAkSYlWrRq8+iocf3xs/+bNoe/551NT11a6doUxY6Bp09j+adPCzoC//JKKqiRJkiRJkiSVBwZOkpQMVaqEYOn002P7MzNhyBB44omUlLW13XaDsWOhZcvY/hkzoG9fmDcvNXVJkiRJkiRJKtsMnCQpWdLT4ckn4fzzY/ujUTj7bHjoodTUtZVddw2h0047xfb/+CPsuy/MmZOauiRJkiRJkiSVXQZOkpRMaWnw73/DZZflHbvkErjrruTXlI/WrUPo1LZtbP/8+WGl0/TpKSlLkiRJkiRJUhll4CRJyRaJwD33wN/+lnfsmmvgppvCqqcUa9EihE4dO8b2L1wI/frBN9+kpi5JkiRJkiRJZY+BkySlQiQCf/873H573rG//x2uuqpMhE7bbw+jRsEee8T2L10K/fvDhAmpqUuSJEmSJElS2WLgJEmpdO218MADefvvuQcuugiyspJe0tYaNYJPPoG99ortX7ECBg6Ezz5LTV2SJEmSJEmSyg4DJ0lKtUsugcceC6uecnv4YTj7bMjMTE1dudSvDyNGhPObclu1Cg48MKyCkiRJkiRJklR5GThJUllwzjnwzDOQttUfy089BUOGwObNqakrlzp14P33YdCg2P61a+FPf4IPPkhNXZIkSZIkSZJSz8BJksqKIUPgpZcgIyO2/8UX4fjjYePG1NSVS82a8NZbcOihsf0bNsBhh8Hw4SkpS5IkSZIkSVKKGThJUlly7LHw+utQtWps/xtvwBFHwPr1KSkrt+rV4bXX4JhjYvs3bw59L7+cmrokSZIkSZIkpY6BkySVNYMHwzvvQI0asf0ffACHHAJr1qSmrlyqVg0Lr045JbY/MxNOOinsDihJkiRJkiSp8jBwkqSyaNCgEDDVrh3bP2oUHHggrFyZmrpyyciAp5+GP/85tj8rC04/HR57LBVVSZIkSZIkSUoFAydJKqv69oWRI6F+/dj+zz+H/feH5ctTUlZu6ekhWLroorxj550HDzyQ9JIkSZIkSZIkpYCBkySVZXvuGVY1NWoU2z9pEvTvD4sXp6auXNLS4KGH4Mor845deinccUfya5IkSZIkSZKUXAZOklTWde0Ko0dD06ax/dOmQb9+8MsvqagqRiQCd90FN92Ud+y66+DGGyEaTX5dkiRJkiRJkpLDwEmSyoPdd4exY6Fly9j+mTPD1ntz56akrNwiEbj5Zrjzzrxjt94KV11l6CRJkiRJkiRVVAZOklRe7LprCJ123jm2/8cfYd99Yfbs1NS1lauvhgcfzNt/zz1w8cWQlZX8miRJkiRJkiQlloGTJJUnrVuH0Kldu9j+BQvCSqfvvktJWVv7y1/gscfCqqfc/v1vOOccyMxMTV2SJEmSJEmSEsPASZLKmx12gDFjoFOn2P5Fi8KZTpMnp6aurZxzDjzzDKRt9Z3mySfh1FNhy5bU1CVJkiRJkiSp9Bk4SVJ5tP32MHo09OgR2798OfTvD19+mZKytjZkCLz0EmRkxPa/8AIcfzxs2pSauiRJkiRJkiSVLgMnSSqvGjaEkSOhT5/Y/pUrYdCgsAqqDDj2WHjtNahaNbb/9dfhqKNgw4bU1CVJkiRJkiSp9Bg4SVJ5Vq8efPABDBgQ279mDRx8MIwYkZq6tnLYYfDWW1C9emz/u+/C4MGwdm1q6pIkSZIkSZJUOgycJKm8q10b3nknBEy5rV8f0py3305NXVs58EB4/32oVSu2f+TIUPrq1ampS5IkSZIkSdK2M3CSpIqgRg144w048sjY/k2bwr51r7ySmrq2st9+YdFV3bqx/ePGhV0AV6xISVmSJEmSJEmStpGBkyRVFNWqhWDppJNi+7dsgRNPhGefTU1dW9l7b/jkk3AEVW5ffRV2Bly2LDV1SZIkSZIkSYqfgZMkVSQZGSFYOvPM2P6sLDjtNHjssdTUtZXu3WHUKGjSJLZ/ypSwCmrRolRUJUmSJEmSJCleBk6SVNGkp8N//gMXXZR37Lzz4IEHkl5Sfjp3hjFjoHnz2P7vvoN+/WDBgtTUJUmSJEmSJKnkDJwkqSJKS4OHHoIrr8w7dumlcPvtya8pH+3bw9ix0KpVbP+sWdC3L/z0U2rqkiRJkiRJklQyBk6SVFFFInDXXXDTTXnHrr8ebrgBotHk17WVXXaBcePCf3P76acQOs2alZq6JEmSJEmSJBWfgZMkVWSRCNx8cwietnbbbXD55WUidGrVKqx0at8+tn/BghA6ffddauqSJEmSJEmSVDwGTpJUGVx1Ffzzn3n7778fLrgAsrKSX9NWmjcPZzp17hzbv3gx7LcfTJ6ckrIkSZIkSZIkFYOBkyRVFhddBP/5T1j1lNujj8KZZ8KWLampK5cmTWDUKOjRI7Z/2TIYMAC++io1dUmSJEmSJEkqnIGTJFUmf/4zDBsG6emx/c88AyefDJs3p6auXBo2hJEjYe+9Y/t//x0GDgznPUmSJEmSJEkqWwycJKmyOflkePllqFIltv+VV+Coo2D9+tTUlUu9evDhh9C/f2z/mjVw0EEhkJIkSZIkSZJUdhg4SVJldPTR8MYbUK1abP8778Ahh8Dq1ampK5fateHdd0PAlNu6dXDooWFMkiRJkiRJUtlg4CRJldUhh4TUpmbN2P5Ro8Ledb/9lpq6cqlRA4YPh8MPj+3fuBGOPBJefz0lZUmSJEmSJEnaioGTJFVm++8PI0aEPexyGz8e9tsPFi1KSVm5VasGr74Kxx8f2795Mxx3HLzwQmrqkiRJkiRJkpTDwEmSKrs+fcKqpsaNY/unTYN994V581JTVy5VqsDzz8Npp8X2Z2bCKafAU0+lpi5JkiRJkiRJgYGTJAn22APGjoUWLWL758yBffaBmTNTU1cu6ekhWDrvvNj+aBTOOgv+/e/U1CVJkiRJkiTJwEmSlK19exg3DnbZJbZ/wYKw0mnKlJSUlVtaGjz8MPz1r3nHLroI7rgjBFCSJEmSJEmSksvASZKUo3XrEDp17Bjbv3RpONPpiy9SUVWMSATuuw+uvTbv2HXXwSGHwOLFya9LkiRJkiRJqswMnCRJsZo1g9GjoWfP2P6VK2HQIBg5MiVl5RaJwO23w6235h17/33o0gU+/DD5dUmSJEmSJEmVlYGTJCmv7baDjz+Gfv1i+9euDUuI3nwzNXVt5YYb4N578/YvXgwHHQSXXw4bNya/LkmSJEmSJKmyMXCSJOWvTp2wXOiQQ2L7N22Co4+G555LTV1buewyGDECmjbNO3bffdC7N8ycmfy6JEmSJEmSpMrEwEmSVLAaNeD11+H442P7MzPh1FPhkUdSU9dWBg2CqVPzZmMAkydDt27w5JMQjSa/NkmSJEmSJKkyMHCSJBWualV4/nn4859j+6NRuOACuOuu1NS1lcaN4e234aGHoFq12LF160L5J5wAv/+ekvIkSZIkSZKkCs3ASZJUtPR0ePzxsH/d1q65Bq67rkwsH4pE4OKLYfx46NAh7/grr0CXLvDpp8mvTZIkSZIkSarIDJwkScUTicA998Att+Qdu+OOkPRkZSW/rnx07gwTJ8J55+Ud+/ln6NcvvI0tW5JfmyRJkiRJklQRGThJkoovEoEbb4T778879u9/w+mnl5kUp2bNcMTU669DgwaxY1lZcPPN0L8/zJuXkvIkSZIkSZKkCsXASZJUcn/9Kzz5JKRt9W1k2DA47jjYuDElZeXnyCNh6tSwqmlrn34atth79dXk1yVJkiRJkiRVJAZOkqT4nHkmvPgiZGTE9r/xBgweDGvXpqaufLRoAR9/DLfdFo6jym3lypCR/fnPZapkSZIkSZIkqVwxcJIkxe+44+DNN6F69dj+jz6CAw+E339PSVn5SU+H664Lq5p22inv+JNPQrdu8PXXya9NkiRJkiRJKu8MnCRJ2+ZPf4IPPoA6dWL7P/ssHJK0ZElq6irAXnvB5Mlw0kl5x2bNCuP33RfOeZIkSZIkSZJUPAZOkqRt169f2LOuYcPY/ilToG9fWLAgJWUVpF49eO45eOYZqF07dmzzZrj88pCjLV6cmvokSZIkSZKk8sbASZJUOnr2hDFjoFmz2P6ZM2GffWDOnNTUVYBIBE49Nax26tkz7/iHH0LnzmHxliRJkiRJkqTCGThJkkpPx44wbhy0bh3bP28e7LsvfPttSsoqTJs24Vynq68OIVRuS5bAwQfDpZfCxo2pqU+SJEmSJEkqDwycJEmla5ddQujUvn1s/6JFYeu9CRNSU1chqlaFO++Ejz7Ku0AL4IEHwtlOM2YkvTRJkiRJkiSpXDBwkiSVvhYtYOxY2GOP2P7ffoMBA2D06JSUVZT994epU2Hw4LxjU6ZA9+7wxBMQjSa9NEmSJEmSJKlMM3CSJCVG48bwySfQp09s/5o1YZ+6995LTV1FaNQI3nwT/vUvqFYtdmzdOjj7bDjuOFixIjX1SZIkSZIkSWWRgZMkKXHq14cPP4QDDojt37ABDj8cXn45JWUVJRKBCy8Mu//tvnve8f/+F7p0CTsHSpIkSZIkSTJwkiQlWq1a8NZbcOSRsf1btsCJJ8KTT6amrmLo1CmETuefn3ds/nzYbz+46abwViRJkiRJkqTKzMBJkpR41arBK6/AqafG9kej8Oc/w/33p6auYqhRAx5+GIYPh4YNY8eysuDvf4d+/WDu3FRUJ0mSJEmSJJUNBk6SpOTIyIChQ+Gii/KOXXYZ3HJLCKDKqMMPh6lToX//vGOffw5du5bZHQIlSZIkSZKkhDNwkiQlT1oaPPQQXHdd3rGbb4bLLy/TodMOO8BHH8Htt0N6euzYypVwwglw5pmwZk1q6pMkSZIkSZJSxcBJkpRckQjcdhvcdVfesfvvh7PPhszM5NdVTOnpcO218NlnsPPOeceHDoVu3WDSpOTXJkmSJEmSJKWKgZMkKTWuuiocjhSJxPY/+SScdBJs2pSauoppzz1h8mQ45ZS8Y7NnQ+/ecM894ZwnSZIkSZIkqaIzcJIkpc7558OwYXn3p3vlFTjySFi/PjV1FVPduqH8YcOgdu3Ysc2b4cor4eCDYdGi1NQnSZIkSZIkJYuBkyQptU4+GV57DapWje1/772Q1qxalZq6SuCUU2DKFOjVK+/YiBHQuTO8+27Sy5IkSZIkSZKSxsBJkpR6hx8eAqZatWL7x4yBgQNh+fLU1FUCu+wCn34aznfaepfApUvh0EPhkktgw4bU1CdJkiRJkiQlkoGTJKls2H9/+OgjqF8/tn/CBOjXDxYuTElZJVGlCtx+O4wcCc2b5x1/6CHYay+YPj35tUmSJEmSJEmJZOAkSSo7eveG0aOhSZPY/u++g333hblzU1FViQ0YAN98A4cdlnfsm2+ge3d4/HGIRpNfmyRJkiRJkpQIBk6SpLKlSxcYNw5atozt/+EH2GcfmDEjNXWVUKNGMHw4PPwwVK8eO7Z+PZx7LhxzDPz2W0rKkyRJkiRJkkqVgZMkqexp2zYciNSmTWz/L7+ElU6TJ6emrhKKROD888OugB075h1//fWQr40Zk/zaJEmSJEmSpNJk4CRJKptatQornTp1iu1ftgz694fPPktNXXHo2BHGj4eLLso7tmBBeDt/+xts3pz82iRJkiRJkqTSYOAkSSq7mjYNZzrtuWds/8qVcMABMGJESsqKR40a8M9/wltvwXbbxY5Fo/B//wf9+sGsWampT5IkSZIkSdoWBk6SpLKtYUP46KOwDCi3detg8GB4443U1BWnwYNh6lTYf/+8Y198AZ07w223waZNya9NkiRJkiRJipeBkySp7KtTB957Dw49NLZ/0yY49lh49tnU1BWn5s3D4qw774SMjNixjRvhhhuge3f46qvU1CdJkiRJkiSVlIGTJKl8qF4dXn8dTjghtj8zE047Df7979TUFae0NLj6avj8c9hll7zj334LvXvDX/4Cq1cnvz5JkiRJkiSpJAycJEnlR5Uq8NxzcM45eccuuggOOwzuvhvGjQtb7pUDPXvClClw6aUhhMotGg3nPu2+O7zzTkrKkyRJkiRJkorFwEmSVL6kp8Ojj8IVV+Qde/ttuOoq6NsX6tWDHj1CEPXcc/DDDyHBKYNq14b77oMvv4QuXfKOz58fzn46/nhYtCj59UmSJEmSJElFMXCSJJU/kQj84x9w660Fz9myBSZNClvtDRkCbdpAkyYhubn9dvjkkzK3V13PnjBhAtx1V9hBcGuvvAIdOsATT5TZ7EySJEmSJEmVVCQa9ZFVRbdgwQJatmwJwPz582nRokWKK5KkUvTvf4fVThs2lPy1aWnQsSPstVdovXtD27Z597ZLgR9+gHPPhY8/zn+8Xz94/PFQriRJkiRJklQSicgNDJwqAQMnSRXewoUwYkTYk+7LL2HqVMjKiu9a9evDnnuG8GmvvaBXL2jQoFTLLa5oFJ59Fi67DH77Le94tWrwt7/BlVdC1arJr0+SJEmSJEnlk4GT4mLgJKnSWbMGJk7MCaC++AKWLIn/eh065KyC2msv2H33cJZUkixZApdeCi+8kP94x47wn/+E0iRJkiRJkqSiGDgpLgZOkiq9aBTmzs0Jn778EiZPDuc8xaN27bDyKXsbvj33hMaNS7Xk/Lz/Ppx/Psybl3csEoELLwzHU9Wpk/BSJEmSJEmSVI4ZOCkuBk6SlI/16+Hrr2NXQf3yS/zXa9MmdhVU585QpUrp1fs/a9fCjTfCAw/kv2tgixbw8MMweHCp31qSJEmSJEkVhIGT4mLgJEnFtGBB7CqoSZNg48b4rlWjBvTokbMKaq+9oFmzUit14kQ4+2yYMiX/8WOPhYcegqZNS+2WkiRJkiRJqiAMnBQXAydJitOmTSHRyb0Kau7c+K/XqlVO+LTXXrDHHlCtWtyX27wZ7r8fbroJNmzIO16/Ptx9N5x1VthyT5IkSZIkSQIDJ8XJwEmSStGiRfDVVzmroCZMgHXr4rtW1arQrVvOKqhevWDHHUucDv3wA5x7Lnz8cf7j/frBY49Bu3bxlSlJkiRJkqSKxcBJcTFwkqQE2rIFpk2LXQU1e3b819tuuxBC9egB3buHVowQKhqFYcPg0kvht9/yjlerBjfcAFddFXIuSZIkSZIkVV4GToqLgZMkJdny5bGroL76Clavjv96DRvmhE/ZrXXrfEOopUtD6PT88/lfqmNH+M9/wqIqSZIkSZIkVU4GToqLgZMkpVhmJkyfHrsK6vvvt+2aDRuGlVDZAVSPHjEh1AcfwHnnwbx5eV8aicCFF8Ltt0OdOttWhiRJkiRJksofAyfFxcBJksqg338P5z/lXgWV3154JdGgQcwqqHUduvO3p3bigQcjZGXlnd6iBTz8MAwevG23lSRJkiRJUvli4KS4GDhJUjkQjcLcuTBpUmwrhRBqVZtuvDavO+8v6c4kuvMjOwM52/Edeyw8+CA0a7Ztt5IkSZIkSVL5YOCkuBg4SVI5FY2GPfGyw6eJE0slhFpBfb6mGxPpwSRCCLW87s7cfU+Es86CtLRSql+SJEmSJEllkoGT4mLgJEkVyNYhVHZbvnybLpsdQi1p0Z1+l3Wn+eDusMsuf5wJJUmSJEmSpIrDwElxMXCSpAouGoWff44NoCZO3OYQKlqvHpFu3XLOherRwxBKkiRJkiSpAkhEbpCxzVeQJEmpFYnAjjuGdtRRoS+/EGrSJFi2rPiXXbkSRo0KLVu9epA7hOr+v5VQ7sMnSZIkSZJUqRk4SZJUERUUQs2fnzeEWrq0+NfNL4SqWzeEUD17wimnQOfOpfteJEmSJEmSVOa5pV4l4JZ6kqQCRaOwYAEbPp3Ipw9OYstXk+jGJJpQghAqt7Q0uPpquOkmqFatdGuVJEmSJElSqUhEbuD+N5IkVWaRCLRsSfUTj2Tgl/9H44nvc1DXxbTkZ47gDW7lBt7jYBbTpHjXy8qCO+6AXr3gm28SW7skSZIkSZLKDAMnSZL0h+7dYfyECH/5R0tG1DiCG7mVQ3iPpiyiBfM5nOH8o9rf+LnjwUSbFBJCTZ0atti77TbYsiV5b0CSJEmSJEkpYeAkSZJiZGTAlVfCtGkwcGB2b4RfaMFbHM7VG//Ojt++x37tFvHD6PkwfDhceilUqRJ7oc2b4YYbYO+9YcaMJL8LSZIkSZIkJZOBkyRJytcuu8CIEfDMM7DddnnHx46LsNsBLbh16uFsuvM+mDABOnfOO3HCBNhjD7j//rDlniRJkiRJkiocAydJklSgSAROPRWmT4dTTsk7vmkT3HgjdOsGX6zrAuPHw3XXQdpWf8XYsAEuuwz694effkpO8ZIkSZIkSUoaAydJklSkxo1h2DD44ANo3Trv+HffQZ8+cM7F1Zh/3m3w+efQtm3eiWPHQqdO8PjjEI0mvG5JkiRJkiQlh4GTJEkqtgMPhG+/hcsvz7uIKRqF//wH2rSBi4btya/vToa//jXvRdauhXPPhT/9CX75JSl1S5IkSZIkKbEMnCRJUonUqgX33BN2z9tjj7zjmzbBv/8NO3esySVZ97P8v6Ngxx3zTvzgA+jYEZ5/3tVOkiRJkiRJ5ZyBkyRJikv37iF0uvtuqFEj7/jGjfDQQ9DilP245pBprDv57LyTfv89HA51zDGwdGnCa5YkSZIkSVJiGDhJkqS4ZWTAFVfA7Nlw4YVQtWreORs2wF0P16HR64/zxJHvkrl9s7yTXn8ddt8dhg9PeM2SJEmSJEkqfQZOkiRpm+2wA/zrXzBnDpx3HlSpknfO+vVw9ht/YsdV3zK5w0l5JyxdCkceCaeeGlY+SZIkSZIkqdwwcJIkSaWmZUt45JGw4unss8MKqK39sr4h3aY/zynVXmVtje3yThg2LJztNGJE4guWJEmSJElSqTBwkiRJpW7HHeHxx2HWLDjrLEhPzzvn+Y3HsPP673g3/bC8g7/8AgceCOefD2vWJL5gSZIkSZIkbRMDJ0mSlDA77QRPPAEzZ8Lpp0PaVn/zWML2HJo5nFN5hpXUzXuBRx+FLl1g3Lik1CtJkiRJkqT4GDhJkqSE22UXGDoUZsyAIUO2Dp4iDONUOvItHzEw74t//BH69YMrroANG5JVsiRJkiRJkkrAwEmSJCXNrrvCs8/C99/DySdDJJIztoCWHMAIzudh1lIz9oXRKNx7L3TrBhMnJrdoSZIkSZIkFcnASZIkJV27dvDcc/Ddd3DCCbmDpwiPcj6dmco49sn7wunTYa+94KabYNOmZJYsSZIkSZKkQhg4SZKklOnQAV58EaZNg2OPzen/kV3Yj9Fczj1soFrsizIz4e9/D8HTtGnJLViSJEmSJEn5MnCSJEkpt/vu8Mor8M03cNRRoS+LdO7jcroziYl0z/uiyZOhRw+4664QQkmSJEmSJCllDJwkSVKZ0bkzvPZayJKOOCL0fc/u9OYLbuQWNpMR+4JNm+Caa2DffWH27KTXK0mSJEmSpMDASZIklTldu8Ibb8CkSTB4MGyhCrdyI3vxJd+ye94XfPEF0S5d4F//gqyspNcrSZIkSZJU2Rk4SZKkMqtbN3jrLZgwAQ45BL6mOz2YyF1cRRaRmLmR9evh4ovJ2n8QzJuXooolSZIkSZIqJwMnSZJU5vXoAe+8A19+Cf0Pqs413MW+jGMOu+SZmzb6Eza178SW/wyFaDQF1UqSJEmSJFU+Bk6SJKnc2HNPeP99+PxzqDWoD134hn9xYZ55VTesJuOcM5nX9TA2/7wwBZVKkiRJkiRVLgZOkiSp3OndG0aMgBGf1mL4/v9iIB/xMy3zzNtx6jus2akjn5z3Cps3p6BQSZIkSZKkSsLASZIklVt9+sDIkXDjmIFcsM80nuKMPHMaZP3GgMeO58MGJ/Div5azZUsKCpUkSZIkSargDJyAefPmcfnll9O+fXtq1apFw4YN6dmzJ3fffTfr1q0r1XuNHDmS008/nTZt2lCrVi3q1atH27ZtOeaYY3jkkUdYs2ZNqd5PkqTKoG9feGdcPXb65Cmu3e1NFrF9njmHrn2Z/S7uyAWt3mHYMAyeJEmSJEmSSlEkGq3cp2m//fbbnHLKKaxatSrf8bZt2/Luu+/Spk2bbbrPihUrOOOMM3jzzTcLnTd58mS6du26Tffa2oIFC2jZMmwzNH/+fFq0aFGq15ckqSyJRmHcG8vYcs4FDFj+ar5znuRM/r3L/Vx+S11OOAHS05NcpCRJkiRJUgolIjeo1CucJk+ezPHHH8+qVauoXbs2t912G59//jkff/wxZ599NgCzZs3ikEMOYfXq1XHfZ+XKlQwaNOiPsOnII4/k+eef58svv2TChAm8/vrrXHLJJQZBkiSVgkgE+h7ViP5LX+Gba19iZUbDPHPO4ine+KETT57yCR07wksvQVZWCoqVJEmSJEmqICr1Cqe+ffsybtw4MjIyGDt2LL17944Zv/vuu7nqqqsAuOmmm7j55pvjus+pp57KsGHDqFatGq+88gqHHXZYvvOi0SiZmZlkZGTEdZ+CuMJJklSZRX9dyNIjz6bJ+HfzHX+Ii7mGO9lpt5rcfDMcfTSkVeqP5EiSJEmSpIrOFU6laPz48YwbNw6As846K0/YBHD55ZfToUMHAB588EE2b95c4vt8+umnDBs2DID/+7//KzBsAohEIqUeNkmSVNlFmjejyZdvE33iSTbXqJNn/C/8kyl0pe73X3DccdClC7zyiiueJEmSJEmSSqLSBk7Dhw//4+szzjgj3zlpaWmceuqpAPz++++MGjWqxPf517/+BUC9evW46KKLSl6oJEnadpEIkbPOpMr3U4n2759nuC2z+ZR9uINrmPXtRo4/Hjp1ClvtZWamoF5JkiRJkqRyptIGTp9++ikAtWrVonv37gXO69ev3x9ff/bZZyW6x6ZNm/44t2nQoEFUr14dgMzMTObPn8/cuXPZsGFDSUuXJEnxat2ayMiR8NBDRGvUiBlKJ4truItpdGJ/RvL993DiiSF4euEFgydJkiRJkqTCVNrAafr06QC0adOm0G3s2rdvn+c1xfXNN9/8ESh16tSJVatW8de//pVGjRrRqlUrdtppJ+rVq8egQYMYPXp0yd/E/yxYsKDQtnDhwrivLUlShZOWBhdfTGTKFNhrrzzDbZnNSAbxAifSlIVMnw4nnwy77w7PP2/wJEmSJEmSlJ9KGTht2LCBZcuWARR5EFaDBg2oVasWEA7OKonvv//+j6+zsrLo0aMHDz74IL///vsf/Zs2bWLkyJEMGDCAu+66q0TXz9ayZctCW69eveK6riRJFVrbtjBuHNxxB1Spkmf4RF5iBu25iH+SRiYzZ8Ipp8Buu8GwYbBlSwpqliRJkiRJKqMqZeC0evXqP76uXbt2kfOzA6c1a9aU6D6//fbbH1/fddddzJ49m4MOOojx48ezYcMGlixZwiOPPEK9evWIRqNcc801f2zBJ0mSkiAjA665BiZNgj33zDNcj1X8k78wnl70YAIAs2bBqadChw7wzDMGT5IkSZIkSVBJA6fc5yZVrVq1yPnVqlUDYP369SW6z9q1a2PuOWjQIN555x169uxJtWrVaNy4Meeddx7vvPMOaWnhf8W1115LNBot0X3mz59faBs/fnyJridJUqXTqRN8/jk89hg0aJBnuDtf8xV78m8uoD4rAJgzB04/Hdq3h6FDYfPmJNcsSZIkSZJUhlTKwKl69ep/fL1p06Yi52/cuBGAGlsdLl6S+0BY5ZSenp5n3j777MNRRx0FhHOipk2bVqL7tGjRotDWrFmzEl1PkqRKKS0NzjkHZsyA007LO0yUC3iEGbTnFIYB4QMiP/wAZ54ZgqennjJ4kiRJkiRJlVOlDJzq1Knzx9fF2SYve6VScbbfK+g+jRs3Zo899ihw7oEHHvjH1xMmTCjRfSRJUilq0gSefhrGjAkHNm1le5YwjFP5hAG0Z/of/T/+CGedBe3awRNPQDE+0yJJkiRJklRhVMrAqXr16my33XYALFiwoNC5K1as+CNwatmyZYnuk3t+ixYtij136dKlJbqPJElKgL59YfJkuPNOqFkzz3B/RvMNXbiN66jBuj/6f/oJzj4b2raFxx83eJIkSZIkSZVDpQycAHb73yeW58yZw5ZCTvueMWPGH1936NChRPfYfffd//g6MzOz0Lm5xzMyMkp0H0mSlCBVq8LVV8P338Phh+cdZjPXcQffsTuH8E7M2Lx5cO65sOuu8Oij8L8deiVJkiRJkiqkShs47bPPPkDYLm/SpEkFzhszZswfX/fp06dE99hxxx1p1aoVAHPnziUajRY494cffvjj6x122KFE95EkSQm2444wfDi89Vb4eis7MZd3GMzrHElLfo4Z+/lnOP/8EDw9/LDBkyRJkiRJqpgqbeB0xBFH/PH10KFD852TlZXFs88+C0D9+vXp379/ie9z9NFHA7Bq1So+/vjjAue9/vrrf3ydHYZJkqQyZvBg+O47uOYayGdF8pEMZ2ZaB67kH2SwOWZs/ny48ELYZRf4979hw4ZkFS1JkiRJkpR4lTZw6tWrF/vuuy8ATz75JF988UWeOffeey/Tp4fDwC+55BKqVKkSMz569GgikQiRSITTTz893/v89a9/pXr16gBcdtllrFq1Ks+c5557jtGjRwNwyCGHlPisKEmSlES1asEdd8A330C/fnmGa2St4x9czcyae7AP4/KM//ILXHRRCJ7++U+DJ0mSJEmSVDFU2sAJ4MEHH6RGjRps2bKFAw44gDvuuIMvv/ySUaNGce6553LVVVcB0LZtWy6//PK47tGqVSv+/ve/AzBt2jR69erF0KFDmTRpEqNGjeLiiy/+I6yqW7cu999/f6m8N0mSlGC77QajRsEzz0DjxnmGd173HePoy3vbn0EjluYZ//VX+MtfYOed4cEHYf36ZBQtSZIkSZKUGJFoYQcLVQJvv/02p5xySr4rjyCETe+++y5t2rTJMzZ69Og/ttk77bTTePrppwu8z7XXXstdd91V4DlOTZo0Yfjw4fTu3bvkb6IICxYs+GPV1Pz582nRokWp30OSpEptxQq47jp47DHI53v95joNeLDZXVw16yyiBXzep2lTuOoqOPdcqFkz0QVLkiRJkqTKLBG5QaVe4QQwePBgpk6dyqWXXkrbtm2pWbMm9evXp0ePHtx1111Mnjw537CppO644w4+++wzhgwZQuvWralWrRr16tWjZ8+e3HrrrcyaNSshYZMkSUqCBg3gkUfgiy9gjz3yDFdZvYIrZp3Dit334c89v8n3EosWwWWXhRVP994La9cmumhJkiRJkqTSU+lXOFUGrnCSJCmJtmyBhx+GG26A1avzjqen88vRf+H8Jbfw9ug6BV6mSRO48ko4//xwbJQkSZIkSVJpcYWTJElSWZeREQ5nmjEDjj8+73hmJju8cj9vzWrPjFtf5YBB+X/2Z8mSEDjttBP84x+wZk2C65YkSZIkSdoGBk6SJEmJ0Lw5vPQSjBgB+W3P++uvtPvbcXyYdjBfvzKHAw/M/zJLl8LVV4fg6c478180JUmSJEmSlGoGTpIkSYk0aBBMmwY33wzVquUd//BD9hjSkQ/2/jtfjd3IwQfnf5lly+Daa0PwdPvtsGpVQquWJEmSJEkqEQMnSZKkRKteHW66Cb79lnyXMm3cCDfdRK+zOvHeZSP56is45JD8L7V8OVx/fQiebrvN4EmSJEmSJJUNBk6SJEnJ0qYNvP8+vPJK2HJva7Nnw6BB9Lr/RN55/FcmTIDBg/O/1G+/wQ03QOvWcOutsHJlQiuXJEmSJEkqlIGTJElSMkUicOyxMH06/PWvkJbPX8deegnat6fH5w/x1huZTJwIhx2W/+VWrIAbbwzB0y23wO+/J7B2SZIkSZKkAhg4SZIkpULdunD//TBpEuy1V97x1avhkkugZ0+6Z47nzTfh66/hiCPyv9zvv4djolq1gssug7lzE1e6JEmSJEnS1gycJEmSUqlrV/jsM3jsMWjQIO/45MkhkDr/fPZovYI33ghdRx2V/+VWrw451i67wHHHwZdfJrR6SZIkSZIkwMBJkiQp9dLS4JxzYOZMOO20vOPRKDz6KLRvD8OG0bVLlNdeg2++gaOPzv+SWVnw6qvQuzfsvTf897+wZUti34YkSZIkSaq8DJwkSZLKisaN4emnYcwY2G23vONLlsCpp8KAATB9Op07hyBp6tSwmim/46AAvvgiHBu1665h9dOqVQl9F5IkSZIkqRIycJIkSSpr+vaFKVPgrrugZs2846NHQ5cucN11sG4dnTrByy/D7Nnh2KfatfO/7Ny54XynFi3g8sth3rwEvgdJkiRJklSpGDhJkiSVRVWqwFVXwfffw+GH5x3fvBnuuCOshHr7bQB23hkeeAAWLIB77oGWLfO/9OrVcN994Zyn44+Hr75K3NuQJEmSJEmVg4GTJElSWbbjjjB8OLz1Vvh6a/PmwWGHwRFHwM8/A1CvXljB9MMP8NJL0LNn/pfOzIRXXoG99oI+feC110KfJEmSJElSSRk4SZIklQeDB8N338E110BGRt7xN9+EDh3goovg0Udh1CiqLP2V44+L8tVX8OmncNRREInkf/nPP4djjgnnPD34YFgFJUmSJEmSVFyRaDQaTXURSqwFCxbQ8n976syfP58WLVqkuCJJkrRNvv8eLrgAxowpem7t2tC2LbRrB+3asbheW579qh33vNWWJesKOOwJqFsXzjkHLr4YWrUqxdolSZIkSVLKJSI3MHCqBAycJEmqgKJReO65sHfe0qVxXWJ1vR2YuqEtUze2YyahzaItc2lNFukApKfDscfCpZdCr16l+QYkSZIkSVKqGDgpLgZOkiRVYCtWwHXXwWOPhRCqFGykKnNo80cAlR1G1e/Vjj9fvR2HHx6CKEmSJEmSVD4ZOCkuBk6SJFUCU6fC66/DjBkwcybMmgXr1pX6bZbTkHnV2lG9Szt2+VM7qnX633Z9bdpAtWqlfj9JkiRJklT6EpEb5HPitCRJksqdzp1Dy5aVBb/8EoKnmTNj27x5ca+G2o7f2G7jFzD+CxifayAtDVq3jjkvinbtwo932AEikW16e5IkSZIkqWwzcJIkSaqI0tKgZcvQ9t8/dmzDBpgzJyeAyh1KrVgR3/2ysuDHH0P74IPYsVq1YoOo7K/btoU6deK7nyRJkiRJKlMMnCRJkiqb6tWhY8fQcotGYdmyPKuiojNmkjXnB9IzN8d3v7VrYfLk0LbWvHlsGLXbbtC3L9SoEd+9JEmSJElSShg4SZIkKYhEoHHj0Pr0yekG0rdsIfrTXL57fSbjh81k83ezaMtM2jGT5iyM/56//hra6NE5fbVrw+GHw3HHwYEHejaUJEmSJEnlQCQajXMDf5UbiTj8S5IkVW6zZ8ODD8LQoZC+bhVtmUVbZtHufyFUO2bSllnUYt223ahePTjiiBA+DRwIVauWSv2SJEmSJFVmicgNDJwqAQMnSZKUKL/9Bo8/Dv/8Z1ioFCvKDvxCO2ayW9pMDmkzk96NZlFv4UyYOzds4VcSDRrAkUfC8cdD//5QpUopvQtJkiRJkioXAyfFxcBJkiQl2qZN8MorcN99+R/VlFvfvnDFRRv4U9s5pP+Q67yo77+HiROLF0Rttx0cfXQIn/r1g/T00nkjkiRJkiRVAgZOiouBkyRJSpZoFMaODcHT228Xnh21aQN//SucfjrUqvW/zoUL4bXX4OWX4dNPi3fTJk3gmGNC+NSnj+GTJEmSJElFMHBSXAycJElSKsyalXPO0/r1Bc9r0ADOPRcuugh22CHXwIIF8N//hvDpyy+Ld9NmzeDYY8OZT717Q1raNr0HSZIkSZIqIgMnxcXASZIkpdLy5TnnPC1cWPC8jAw44QS4+GLo2RMikVyD8+bBq6+GffsmTCjejVu0CMHTccdBr15bXVCSJEmSpMrLwElxMXCSJEllwaZNYbHSfffBlCmFz+3WDc4/H048Mdd2e9l+/DEET6+8UvSBUdl23DEET8cfHy5u+CRJkiRJqsQMnBQXAydJklSWRKMwenQInt55p/C5devCqaeG8Gm33fKZMGtWWPn08sswbVrxCthll5zwqXNnwydJkiRJUqVj4KS4GDhJkqSyaubMcM7T008Xfs4TQN++IXg66iioWjWfCdOnh1VPL78cvi6Odu1ywqfddy9p+ZIkSZIklUsGToqLgZMkSSrrss95euyxcFxTYZo0gbPOgnPOgdat85kQjcJ334Xg6eWXYfbs4hWx224heDruOGjfvqRvQZIkSZKkcsPASXExcJIkSeVFZiZ88AE88gi8917IjgoSicCf/hRWPR10EKSn5zMpGoVvvgnB0yuvhPOfiqNz55yVT23axPVeJEmSJEkqqwycFBcDJ0mSVB7NnRtWPT35JCxZUvjcHXeEc8+FM8+E7bcvYFI0CpMmheDplVeKXkqVrVu3ED4ddxzstFNJ3oIkSZIkSWWSgZPiYuAkSZLKs02b4PXXw6qnsWMLn1ulSjjj6fzzw5lPkUgBE6NR+OqrnPDpl1+KV0yvXjnh0//+fiVJkiRJUnlj4KS4GDhJkqSK4rvv4NFH4dlnYdWqwufuthucdx6ceirUq1fIxKws+OKLsO3eq6/CokXFK6Z377Dl3rHHQvPmxX4PkiRJkiSlmoGT4mLgJEmSKpo1a+DFF8Oqp8mTC59bsyacdFJY9dStWxEXzsyETz8N4dN//wtLlxZdTCQC++wTwqejj4amTYv9PiRJkiRJSgUDJ8XFwEmSJFVU0SiMHx+Cp5dfhg0bCp/fq1cIno4/HmrUKOLiW7bAmDFhy73XXoPly4suKC0NWrQIIVR2S0uL/XF+fWVpTq1a0L8/HHlk+FqSJEmSVOEYOCkuBk6SJKky+O03eOaZsOXerFmFz23QAE4/PWy517ZtMS6+eTOMGhVSrddfh99/L4WKy7jatcN2gaedBvvuG0IpSZIkSVKFYOCkuBg4SZKkyiQahU8+Cauehg8Pu+QVZv/9w6qnww6DKlWKcYNNm2DkyBA+DR9e9GFSFUHr1jBkSDgQq02bVFcjSZIkSdpGBk6Ki4GTJEmqrH79FZ54Ah5/HH75pfC5zZrB2WeHVuy/Lm3cCB9+GMKnt94Kh0tVdHvvHVY9HXcc1K+f6mokSZIkSXEwcFJcDJwkSVJlt2ULvPNOWPU0YkThc9PTYfDgsN3eoEEl2Elu/XqYMCGETtFoTsvKKtmPUzknKwsmToSPPgpfF6ZaNTjiiLDq6YADICOjmD9RkiRJkqRUM3BSXAycJEmScsyZA489BkOHwvLlhc/dZRc491w44wxo1Cg59ZUJv/4Kzz8fDsX67rui5zdtCiefHMKnzp0TX58kSZIkaZsYOCkuBk6SJEl5bdgAr74aVj198UXhc6tVg2OPDWc99e4NkUhyaky5aBS+/hqefRZeeAGWLSv6NV27huDppJNg++0TXqIkSZIkqeQSkRsUd4MQSZIkqUKpXh2GDIHPP4cpU8IWerVr5z9340Z47jno0yfkKY8+CqtXJ7PaFIlEoHt3ePDBcAjW8OFw1FFQpUrBr5kyBS67DHbYIexN+N//hnRPKi+iUZg7F9auTXUlkiRJUrli4CRJkqRKr0uXsNLpl1/g4YehU6eC506dGlY6NW8OF1wA06Ylr86UqloVDj8cXnsNFi6Ef/0LevUqeH5mZjg469hjoVmz8JP25ZfhYb5UVo0YEVLlnXaC7bYLv37fegs2bUp1ZZIkSVKZ55Z6lYBb6kmSJJVMNBpWPj38cFigU9Sz5j59Qp5y9NFh5VSlMn162HJv2LCQ2BWlbduw5d6QIdCqVeLrk4pj2jS48kr48MP8x7fbDo4/Pvy63XPPSrSvpiRJkioqz3BSXAycJEmS4rd0KQwdGrbR++mnwuc2agSnnw5nngkdOiSlvLIjMxNGjYJnnoHXX4d16wqfH4nAfvvBaaeFpK6g/QylRFq4EG68EZ56CrKyiveaNm3glFPg5JPD15IkSVI5ZOCkuBg4SZIkbbusrLDb1iOPhJ3iino2veeecMYZcMIJUK9ecmosM1avDlvvPfMMjB5d9PxatULodOqp0L8/pLnztxJs7Vq45x64++5tO6tpr73Cqqfjjw+roCRJkqRywsBJcTFwkiRJKl0//wz/+Q888QQsWlT43OrV4aijQvg0YEAlzFLmzg3b7T37LMyZU/T8li3DA/xTT4V27RJeniqZzMwQhN5wQ1jdlJ+mTeHvfw9zn3sOPvus6OtmZMCf/hR+7R56aCXcW1OSJEnljYGT4mLgJEmSlBibN8Pw4WHV06hRRc9v1SrsIHfaabDLLgkvr2yJRuGLL8LD/pdfhpUri37NnnuGn6zjj4eGDRNfoyq2jz6CK66AqVPzH69ZM5zjdMUVsVs8/vgjPP98CE5nzy76PvXqwbHHhm339t23EqbMkiRJKg8MnBQXAydJkqTEmzEDnnwyPJNevLjo+X37hlVPxxxTCY8v2rAB3norhE8ffhhWkhSmalUYPDiETwcdBFWqJKdOVQzffgtXXQXvv5//eCQSDl77+9+hefOCrxONwoQJ4Tf5Sy/BsmVF37tVq3DW05AhlfBgt0ooKwsWLAjB5KxZYRVdw4bQrFn4tdWsWWi1aqW6UkmSJAMnxcfASZIkKXk2b4YPPoChQ+Htt2HLlsLn16oFxx0Xwqd99gnPviuVRYvghRdC+FTQypPcGjeGk04K4VPXrpXwJ0zFtmgR3HhjSIILOnRt0KBwllPnziW79ubNISwdNiyEpxs2FP2abt1C8HTCCWHbPpVP0WgIG2fNCi07XMr+uji/FurUyQmfcgdRuVvz5lC3rn/GSZKkhDFwUlwMnCRJklJj6dKwE9fQocXLUtq0gdNPD8cX/e+vb5XLlCnhrKfnn4clS4qe37FjCJ5OPjk8oJUA1q2De++Fu+6CtWvzn7P77iFoOuigbb/fypXw2mvhvKfRo0MgUZj09BB0DRkChx/uapeyavXq2DApd7j0++/JqaFGjfyDqK37ttvOYEqSJJWYgZPiYuAkSZKUWtFoyFKGDg1Zym+/FT4/EoGBA8OqpyOOCM8cK5Xs1SPPPgtvvgmbNhU+Py0NDjwwJHWHH14Jf8IEhK0Zhw2D66+HX3/Nf07TpnDrrSHZzcgo/Rrmzw8r9oYNg+++K3p+7dpw1FHhvKcBA0IYpeTZuBF++CHvSqVZs8IKufKiSpWCV0nl/nHjxv4akyRJfzBwUlwMnCRJksqOjRvDVntDh4at9wra6StbvXpw4okhfOrZsxJ+iH3FCnj55bDl3pdfFj2/Xj04+OBwdk5+D2Ar3YFZlcTHH8MVV4RkNz81asCVV4aWjF8D0Sh8800Inl54oXjhRbNmYbvIIUPCFn+V7jd7gmRmws8/579Sad68ov8Qjkft2rDrruHPoRUrwllOCxfCmjWlf6+SSE+HJk0K38avWTPYfnvPypMkqRIwcFJcDJwkSZLKpl9/Dc+jhw6FmTOLnr/bbiF4OuWUSnoEzKxZYdXTsGHhAXI8atfO/0FrdmvaNPy3YUMf+JcH338fQqT33st/PBIJq5luvRV22CGppf0hMzMEYs89B6+/XvA2f7l17BiCp5NOAv/9VrRoNIR6+Z2r9MMPRa+SjEeVKmEf1LZtQ7jUtm1Oa9o0/z8/Vq/OCZ+2br/+mvN1srbsK0gkAo0ahT8L27SBI48Mze0fJUmqUAycFBcDJ0mSpLItGoWvvgrB00svwapVhc9PTw+LeM44Aw49FKpWTU6dZUZWFowZE1Y9/fe/xXuAX1JVq+aET4W1Jk3coioVFi+Gm26C//yn4BUqAweGc5q6dElubYVZuxaGDw+h6UcfFb26JhKB/v1Dynz00VC3blLKLLNWrCj4XKVErB6KRGDHHWPDpOyAqVWrxGzLCLB+fQjQcodQ+YVTy5Yl5v75qVUrZ/vH/ff3zz1JkioAAyfFxcBJkiSp/Fi3Dt54I4RPn3wSwqjCNGoEJ58cwqey9Fw9adasCT9hzzxTvJ+w0paWFkKnooKppk2hWrXk1lYRrVsH998Pd95ZcMCw224haDrooLK9Sm3RInjxxRA+TZ5c9Pzq1cOhbqecAgccUPG2PNuwAZYvDyHK8uWwdCn8+GNsuJSogKVp0/xXKu28c/h5L6s2bQrha36rpHK3xYtLd+vAZs3CXq9DhoRvPGX595kkSRD+jfDyyzB4sCt2czFwUlwMnCRJksqnefPCDnJPPx2euxZljz1C8HTSSbDddgkvr+z5+Wd4883wk7VoUewD19WrU11d2KavqGDKc6byl5UVtqS7/npYsCD/OdtvD3//O5x5ZuJWniTKd9/B88+H9zh/ftHzGzeGE04ID/x79Ch7D/xzh0fZAVJRXydipWJu9erlv1Jp110r/sqxzExYsqTwbfwWLgx/bm7eXLJrd+wYQtCTT3b7R0lS2bRyJZx7bgiczjwTnnwy1RWVGQZOiouBkyRJUvmWlQXjxoVVT6++GhZ5FKZKFTjssBA+HXhg+Xv2nhBr1uQNofJry5enulKoUyekh337hta7d+UOoUaNgssvL3gVUI0acMUV4SynOnWSW1tpy/7NPmxY+M1e1P6aEIKTIUPCA/+ddir9mjZsKH5wlP3fRIdHBalePWeV0tarlRo1KnvBXFmTlQW//ZYTRM2bF1aQjhhR/O0fhwwJW+9V9BBPklQ+fPllWJU7d25O34svhg/uyMBJ8TFwkiRJqjhWrw7PoYcOhU8/LXp+s2bh+d8ZZ0D79omvr9zbuDF2i6qCWmlvUVWY9HTo3j0ngNpnH2jQIDn3TqXp0+Gqq+Cdd/Ifj0TgtNPg//4PdtghubUlw/r14b0PGwbvvw9bthT9mn32CatNjjsu/18j69eXfOVRUQl3sqWnh2Bt65VKbduGFTZpaamusOJZtCgcMDhsGHz9ddHza9SAww8P33wGDap42z9Kksq+zEz4xz/gb38LX+dWt27YEaFSbgkRy8BJcTFwkiRJqpjmzAnb7T3zTMG7jOW2114heDr++LC7lLZBZmY4Y6aoYGrhwnDOSmmKRKBTp5wAat99wxk0FcWSJXDzzfD443kfEGTbf/9wTlPXrsmsLHWWLQvbwDz3XPikblGqVg2rTbKyYgOkshYe5ScSCdtPNmoEzZvn3QZvp50MMFLp++9D8PT888Xf/jH7vKfu3V1lJklKvF9/Dd93Pvkk71iDBmFLvSOPTH5dZZCBk+Ji4CRJklSxZWbCxx+HVU9vvBEW6RSmevWw49EZZ8CAAS4ISKhoFFasKF4wtWZN/Pdp2zYngOrbF3bcsfTeQ7KsXw8PPAB33FHwmVsdOoSg6eCDK++D69mzc857+uGHVFdTuNzhUaNG4ZPERX1dv35YxaSyLSsLxo4Nvw6Lu/1j+/Y55z21bp3wEiVJldC778Lpp4cP2mxt333D961WrZJeVlll4KS4GDhJkiRVHitWhIUQQ4fC+PFFz2/VKuxKdvrpsPPOCS9Phck+Z2rWrHCOz5gxMGFC8bZS21qrVrEBVNu2ZTegycoKAcr11xe8YqJJE/j73+GsszyULFs0GlY7DRsWftP/9lti7xeJhGCoOKFR9teGR5XD+vXw9tvhIV5xt3/s2zeET8ceG36dSGXRli3w7LMwcWJ4UH3MMa6wlMqqjRvh6qvhwQfzjqWlwY03hr9r+vfIGAZOiouBkyRJUuX03Xdhy71hw8KRQ0Xp1y8ET8ccA7VrJ7o6Fcu6dSFUGDs2tC++gA0bSn6dJk1iA6hOncrG0rbRo+Hyyws+F6Z69TB+9dVQp05SSytXNm0KD/qHDQsP/ovaxjEtLWflUXEDJMMjFcfSpTnbP371VdHzq1WDwYND+HTwwWE7SKksmDoVzjwTJk3K6WvZEi69FP78Z78nSWXJzJlwwgkwZUresRYtwgeb+vZNelnlgYGT4mLgJEmSVLlt3gwffBBWPb39dtEfPq9ZM2y5N2RIOCrHZ8xlyKZN4ZPW2QHUp58WvP1cYerXh332yQmgunVL7qe2Z8wIIdJbb+U/HomEX4C33RYeFKj4fv8dhg8Ph7zVq1fwtnVlIXBUxTZrVgiennsOfvqp6PnbbRcOGTzllHDoYFldlamKbdMmuP328P2noL8w1a8P558Pf/lLxTpDUSpvotHw6bqLLsr/nMojj4QnnggfslG+DJwUFwMnSZIkZVu6FF54IYRP33xT9PxmzeCkk8Kz/y5dEl+fSmjLlvAp7OwAauxYWL685NepWRP23jsngNpzz7C6qLQtXQq33AKPPhoOH8tP//7hnKZu3Ur//pKSLxqFzz8PK/BeeSXs/VqUXXYJwdMpp0CbNomvUYLwgY4zz4Rp04o3v2rV8BekK64IZ5RJSp6VK0Pw++KLeceqVYP774fzzvPDC0UwcFJcDJwkSZKUn8mTQ/D0/PPFO/6lU6ec89532CHx9SkOWVlh9VB2+DRmDPz6a8mvU7VqCJ2yA6jevbdt+6D168Oe+rffXvCKrA4d4O674U9/8uGAVFFt3AjvvRfCp3feCUtwi9K7d3iof9xxYRWUVNo2bICbbw7fg7Ky8o7Xrx9WjxbmsMPgqqugT58EFCgpxldfwYkn5r96drfd4KWXwj9cVCQDJ8XFwEmSJEmF2bgxPPcbOjRsvVfQwpNskQgMGBCe/x11lMcYlGnRaPjH+JgxOSHUjz+W/Drp6WHFUXYAtc8+xdueJCsrfPL0uuvg55/zn9O4Mfz97+FMDA9yliqP336DV18N4dNnnxU9v0qVEEgPGQKHHJKYVZiqfD7/PKxqmjkz71h6OlxzDfztb2H10913w5tvFn693r3hyivh8MPdulQqbVlZ8I9/hN+T+W15ee65cN99YeW+isXASXExcJIkSVJxLV4cPhQ4bFjsOdkFqVkTjjgiPP8bONC8oFxYsADGjcsJoL7/Pr7rdOqUE0Dtu2/YfzG3sWPh8svDQ7r8VK8Ol10WznKqWze+GiRVDD/+GJbbDhsGs2cXPb9+fTj22PDNp08fH+yr5Nauheuvh4ceCh/O2FqXLuGTOHvsEds/Ywbcey88+2w476kgbduG74Gnnmo4KpWGhQvD76eRI/OO1a8fzmo6+uikl1XeGTgpLgZOkiRJisf06eHZ33PPwfz5Rc9v2jTsbjFkCHTt6q5o5cbSpfDppzkB1JQp+W8pVJRddw3h0957w9tvw/DhBc8dMiQcyP6/f6dIEhAe/I8fH77xvPQSLFtW9Gtatw57vQ4ZAu3aJbxEVQCjRoVVtfmt+K1SBW68MXwYokqVgq+xcCH885/wyCOFb7e3/fZw8cXhrJnirAyWlNd778Fpp+X/PaFPn3BAbatWya+rAjBwUlwMnCRJkrQtsrJCDjFsGPz3v7BqVdGv2X338Ozv5JPBv36WMytXhi2GsgOoCROKd85Kcey3X/hkeLdupXM9SRXX5s1hn9fnngvbmG3cWPRrevQI33xOOAGaNEl8jcURjYaVMJs2hfeQ/d/cXxf237p1Yf/9oUGDVL+T8m/VqhAkPfpo/uM9e8JTT0HHjsW/5urVYWXF/fcX/umcWrVCyHXppbDjjiWrW6qsNm6Ea68Nv7+2lpYGN9wQttdzi4W4GTgpLgZOkiRJKi3r18Nbb4XwqbjnPfXvH57/HX205z2VS+vWhcOZswOoL74IvxBKol27cPbFoYe69E1Sya1cCa+9Fr75jB5d9Pz0dDjoIDjlFOjQoXjhTnEDoJK+pjQC+9q14cILwzakZSVIK28++ADOOSf/UKh6dbj1VvjrX+N/cL15M7zySjhfZurUguelp8Pxx4dznrp2je9eUmUwa1bYOuHrr/OO7bBD2Ia1X7/k11XBGDgpLgZOkiRJSoQlS3LOeyromJ7catTIOe9p0CA/jFhubdoUDvgaMyYEUJ9+Gj7hnZ/GjeGWW8KnugvbmkiSiuvnn8P2ScOGxX8GXXlVowacdx5ccQU0b57qasqHFStCUPf00/mP77MPPPlkOHOpNESj8NFH4UMW+Z01k9vAgXDVVeG/fhhDCqLRcEbahReGs9a2dvjh4ffsdtslv7YKyMBJcTFwkiRJUqLNmJFz3tPPPxc9f/vtc8572mMPn7OUa5mZ8M03OSugPvss9J19NlxzDdSrl+oKJVVE0ShMnhy++bz4IixenOqKkqdaNTjrrBBWuD1bwd58MwR0ixblHatVC+68Ey64IGzNlQhffw333BNWPhW2JLxr17Di6dhj/XCGKrdVq8J5Zy+8kHesWrWwLfMFF/gPh1Jk4KS4GDhJkiQpWbKyYNy48Pzv1VeLd97TbrvlnPf0v7+2SpJUfFu2hNUkw4bBG2+UfNvPVIlEwkPUqlXz/29aWgj0s7Lyf31GBpx2Wgj327RJbu1l2dKl8Je/hGXY+dl/f/jPf2CnnZJTz9y54QyaJ54I29QWpFWrcMbTn/8ctlGUKpPx48On0X78Me9Yhw7h93Pnzsmvq4IzcFJcDJwkSZKUCuvXw9tv55z3tGVL4fMjkbAV+5AhcMwx4Zx0SZJKZPXqEDoNGxY+AbFlS8GBTnH/m6jXpqcX/Un9WbPgjjvC+ylolUxaGpx0Elx3XXgwW1lFo/Dyy3DxxbBsWd7xunXDComzzkrNConly+GRR+Cf/wz7EhekQYOwyuPii6Fp0+TVJ6VCVlZYCXj99fn/Y+Hss+GBB6BmzaSXVhkYOCkuBk6SJElKtaVLc857mjCh6PnVq4ct2ocMgQMOcIcZSVIcotGKs/XSTz+FLeCGDoXNm/OfE4mET2xcfz106ZLc+lJt4cIQ0rz5Zv7jf/oTPPYYlIVnYuvXhzNq7r0XZs8ueF61anDqqXD55dCuXfLqk5Jl0aLwa/yjj/KO1asXViIee2zy66pEEpEbJGiTUkmSJEnK0bhx+KDu+PHhvKcbboDWrQuev2FD+JDyoYfCDjvAJZfApEnh2aEkScVSUcImCNu/PfZY2G7q4ovDJzO2Fo2G/Wy7dg2f2ijOJzzKu2gUnn467M+bX9jUoEH4tMs775SNsAmgRg0491yYPh1efx322iv/eRs3hgfuHTrAkUfC558nt04pkT74IGyRl1/YtPfeYTtRw6ZyycBJkiRJUlK1awe33go//ABjx4ajCurVK3j+0qXw0EPQowfsvjvcfjv8/HPy6pUkqcxo0SJ8U/zpJ7jiCqhVK/95b70FvXrBQQfBZ58lt8Zk+flnOPhgOOMM+P33vONHHQXffw+nnFI2w8f09Jwgadw4GDw4/3nRKAwfDn36wD77hGCtoHO9pLJu06bwZ9fBB4e/5OcWiYRPpY0ZAzvumJr6tM3cUq8ScEs9SZIklXUbNuSc9/T++0Wf9wSx5z0VFlhJklRhLVsWzjf55z9h1aqC5+23H/ztb9C/f9kMX0oiKwsefxyuvBLWrMk73rgxPPxw+AtCeTN9ethqb9iw8GC+IO3ahYf2p5yS/2o3qSyaPRtOPDFsW7C15s3h+efDn1VKGs9wUlwMnCRJklSeLF0Kr7wSnrV89VXR86tXh8MOC+HTgQd63pMkqRL6/fcQOj3wAPz2W8Hz9t47rCA46KDyGTz98AOcfTaMGpX/+Mknh5+DRo2SWlapW7gwrGR75BFYubLgedtvH/YdPu+8sH2gVFYNGwYXXJB/SDx4MDz1VPn/fVsOGTgpLgZOkiRJKq9mzYLnngvtp5+Knt+4cfjg5JlnVr7z0iVJYvXqEFLcey8sWVLwvO7dQ/B02GGQVg5O3MjMhH/9C667DtatyzvevDk8+mjB29KVV6tXh3Oc7r8fFiwoeF6tWiGIu/RSaNUqefVJRVm9OgRNzz2Xd6xaNbjnHrjwwvIZgFcABk6Ki4GTJEmSyrtoNBxBMWxYWP2U31ENW+vePZwPdeKJbrknSapk1q0LQcU//gG//lrwvE6dQvB09NHhTKGyaMYMOOuscNZRfs46Kzy0rl8/qWUl1ebN8PLL4f/ntGkFz0tPhxNOCNsN+smbomVmhq0Ls9vGjQX/ON6x7B9Xrw5du4az1bp2rRxbIU6cGH49/vBD3rH27eGll/x1mmIGToqLgZMkSZIqkg0b4N13Q/j03nvhGUxhatQIxzicdRb07esHKCVJlciGDfD003DnnTBvXsHz2rcPq4dOPBEyMpJWXqG2bAkrtW66KTyw31qrViFUO+CA5NeWKtEojBgRgqdPPil87gEHhOBp//2T+5efaDRvkLNpU/gL27b0lTTgKc5YZmbyfl5yy8gIQUuvXjmtffvysdqwOLKy4L774Npr8z+Y9c9/Dltf1qqV9NIUy8BJcTFwkiRJUkW1bFnOeU9ffln0/F13DdvtnXYaNGuW+PokSSoTNm8O3yxvvz3/1QbZdt45PCQ+9VSoWjV59W1t2jQ44wyYNCn/8QsuCCFanTrJrassmTQJ7r4bXn01POAvyB57hJ/LKlVKJ/gpTp9Krk4d6NEjNoTaYYfy90mpxYvDX7Q//DDvWL168PjjcNxxya9L+TJwUlwMnCRJklQZzJ4Nzz4LQ4fCL78UPjc9HQ45JKx6+tOfys6HuSVJSqgtW8LWbLfdBtOnFzyvZUu4+urwjTKZW39t2gR33BHqy28J8y67wJNPQr9+yauprPvpp3DG05NP5n++lcqvZs1iA6gePcr21pEffhjC6vzOj9trL3jxRWjdOullqWAGToqLgZMkSZIqk8zM8O/dJ5+Et97KfyeP3Jo1Cx/EPPPMsAJKkqQKLysLXn8d/u//4JtvCp7XtGnYlu3ccxO//dWkSWElTn5nFEUicOmlcOutULNmYusor5Yvh4cfhn/+E5YuTXU15V9aGlSrFlb6ZbeS/HjrsYULYfz4EPRuy+P4du1iQ6guXcK9UmnTJrj++nCW2tYikbBq8uabwyo7lSkGToqLgZMkSZIqq8WLww5CTz4ZzhwvSr9+YVv5o48OZz9JklShRaPwzjshyJkwoeB5jRrBZZfBhRdC3bqlW8OGDXDLLWF7uPzO1OnQAZ56KqyQUNHWr4dnngnnX82Zk+pq8opEYoOYKlVif5xfX5UqhYc5JQl+ijs3PT0x73/VqhCujh+f0xYsiP96VapA166xIVTbtsk7D2rOnHD228SJeceaNYPnnoMBA5JTi0rMwElxMXCSJElSZReNwuefh+Dp5ZeL3nGmXj046aQQPnXrlpwaJUlKmWgUPvooBE+fflrwvPr14ZJLQmvQYNvv+/nnYYnxzJl5x9LTw7Z+f/tbcrf1qygyM2H48PDA/5dfcsKU/AKe4gY/pdGXnl7+ziVKtF9/DYFvdgA1YQKsXBn/9erWhZ49Y0Oo5s1Lr95szz8P550Ha9bkHTv00LDPdaNGpX9flRoDJ8XFwEmSJEnKsWpVCJ2efBK++qro+V27hiMsTj65dJ6tSZJUpo0ZE4Knjz8ueE6dOmG102WXQePGJb/H2rVwww3w4IP5by/WuXN4WO2nPlQZZWWFw0lzr4KaMiVsXRevHXbIex5UvKsVV6+Giy4Kh6durWrVsFrx4osNFssBAyfFxcBJkiRJyt+334bgadiwcPRBYapVC1vtnXUW7Ldf8nYqkSQpJb74Ipzx9N57Bc+pWTOscLjiirB9VnGMGhWWEP/4Y96xKlXCiqarrw4PriUFGzfC1KmxIVRx9osuSCQC7dvHhlCdOxf9+27SJDjhhPy3a2zXDl56KXxaS+WCgZPiYuAkSZIkFW7jRnjzzRA+ffRR0Wc577xz2AHo9NPDB0YlSaqwvv46BE9vvFHwnGrVQoh01VXQqlX+c1atCkHSo4/mP96zZzirqWPHba9ZqgxWrgxnJ2UHUF99BQsXxn+9qlVhjz1iQ6g2bcKnrLKy4P774dprYfPmvK8980x46CGoVSv++yvpDJwUFwMnSZIkqfjmzQu7+AwdCj//XPjctDQ4+ODwjO2QQ8IHsyVJqpC+/RZuuy3sS1vQ48QqVeC008JD6Z13zun/4AM45xyYPz/va6pVC1v4XXopZGQkpnapsvjll9hVUBMmhC3w4lW/fgiDN20K221urW5deOyxsOpJ5Y6Bk+Ji4CRJkiSVXGYmjBwZVj0NH57/hzlz2357OPXUsOVeu3ZJKVGSpOSbORPuuAOeey58s8xPejqcdFI45+nRR+Hpp/Of16dP+EbrN04pMbKywu/Z3CHUN98U/Rfb4thzT3jhhdhwWeWKgZPiYuAkSZIkbZulS8NztSefhO++K3r+PvuE4OnYY91ZRJJUQf34I9x1V1gSXNKH1zVrwp13hkDKQxGl5NqwIYROuUOoWbOK//pIBK65Bm65xeX95ZyBk+Ji4CRJkiSVjmg0bI//5JPhTOQ1awqfX6cOnHhiCJ969gz/PpckqUKZPx/uvhv+85/wILsoAwaEua6KkMqOFSvynge1eHHeeU2bhk9h7b9/8mtUqTNwUlwMnCRJkqTSt2YNvPJKCJ8+/7zo+Z06heDplFNgu+0SX58kSUm1aBHcey88/DCsW5d3vE6dMP7nP/sJDKmsi0ZhwYKcAOq770JI/Le/QePGqa5OpcTASXExcJIkSZISa/r0EDw9+2zYfq8wVavCkUeG520DBriTkCSpglm2DB54AP75T1i1KvT96U/hLKf/PZ+SJKWegZPiYuAkSZIkJcemTfD22yF8+vDDcE5zYVq3hjPOCM1ncJKkCuX332HUKGjWDPbc01VNklTGGDgpLgZOkiRJUvLNnw9PPw1PPQVz5xY+NxKBAw8MW+4ddlhYBSVJkiRJiZKI3MDNGyRJkiQpAVq2DNvc//ADfPQRnHBCwUFSNAoffADHHgstWsB558Frr4XzmyVJkiSpPDBwkiRJkqQESkuDgQPhxRfh11/hwQehU6eC5y9dCo89BsccA40ahV2IbrgBxowJW/ZJkiRJUllk4CRJkiRJSbLddvCXv8A338D48XDuuVC3bsHzs7LCvNtug/32g4YN4ZBDwlns330XVkZJkiRJUllg4CRJkiRJSRaJQM+e8OijYdXT00/DvvsW/bq1a+G99+DSS6Fjx7D93mmnwXPPwcKFCS9bkiRJkgoUiUb9TFxFl4jDvyRJkiSVvlmz4M03w5lP48bBhg0le33HjjBoUGh9+0KtWompU5IkSVL5lojcwMCpEjBwkiRJksqfDRvg009h5MgQQH39dcleX7Uq7L13TgDVrRukpyemVkmSJEnli4GT4mLgJEmSJJV/y5bBxx+H8Omjj+Dnn0v2+gYNYMCAnABq550TU6ckSZKkss/ASXExcJIkSZIqlmgUZs/OCZ9GjYJVq0p2jZ13zgmfBgwIgZQkSZKkysHASXExcJIkSZIqti1bYPz4nO33vvwy9BVXWhr06JETQPXuHbbkkyRJklQxGTgpLgZOkiRJUuWyahWMGZOzAmrGjJK9vmZN6NcvJ4DafXeIRBJTqyRJkqTkS0RukLHNV5AkSZIklSl168LgwaEBzJ+fs/pp5EhYurTw169bB++/HxpAs2YwcGAInwYODD+WJEmSpNxc4VQJuMJJkiRJUrasLJg6NSd8GjsWNmwo2TU6dswJoPr1g1q1ElOrJEmSpMRwSz3FxcBJkiRJUkE2bIDPPsvZfm/yZCjJvxKrVIG9987Zfq97d0hPT1y9kiRJkradgZPiYuAkSZIkqbiWLYOPP84JoH7+uWSvb9AA9tsPevSArl1Da9bMM6AkSZKkssTASXExcJIkSZIUj2gUZs/O2X7vk09g1aqSX6dx45zwaY89wn/btnUllCRJkpQqicgNMrb5CpIkSZKkCikSCcFQ27Zw4YWwZQtMmJCz+unLL0NfUZYuzXlNtho1oFOn2CCqUyfPg5IkSZLKK1c4VQKucJIkSZKUCKtXw+jROWHSjBnbdr3sgCs7hMpuTZtuc6mSJEmScnGFkyRJkiSpzKhTBwYPDg1gwYKw9d6kSTBlSmhr1hT/etEozJwZ2ssv5/Q3bZo3hGrTxi35JEmSpLLEFU6VgCucJEmSJKVCVhb8+GNO+JTdfvll269dqxZ07hwbQnXsCDVrbvu1JUmSpIrOFU6SJEmSpHIjLS2sRGrTBo45Jqd/6dK8IdSMGSGgKq61a+GLL0LLfb927XLOhMoOoho3LoU3I0mSJKlQBk6SJEmSpKRq3BgGDQot2/r18O23MHlyTgj1zTewbl3xr5uVBdOnh/biizn9zZvnhE/ZQdTOO4eASpIkSVLpMHCSJEmSJKVcjRrQs2do2TIz4YcfQviUO4hatKhk1/7119Deey+nr3Zt6NIl75Z81atv6zuRJEmSKicDJ0mSJElSmZSeDm3bhnbccTn9ixaF1U+5g6hZs6AkJxSvWQOffRZa7vt16BDCp333haOPhu22K6U3I0mSJFVwkWi0JH8lV3mUiMO/JEmSJKksWbsWpk2LPRdq6tSwVV+8qlSBgw6Ck0+GwYOhZs1SKlaSJElKsUTkBq5wkiRJkiSVe7VqwV57hZZtyxaYPTs2hJo8GZYuLd41N2+Gt98OrXZtOOqoED4NGAAZ/mtakiRJiuEKp0rAFU6SJEmSFESjsHBhbAg1ZUoIpopr++3h+OND+NSzJ0QiialVkiRJSpRE5AYGTpWAgZMkSZIkFW716rAl3+TJMHo0vPMObNhQ9Ot23RVOOimET7vumvAyJUmSpFKRiNwgbZuvIEmSJElSOVenDuy9N1x4Ibz6KixeDEOHwsCBkFbIv5xnz4ZbboG2bcNqpwcegEWLkla2JEmSVGYYOEmSJEmStJW6deH00+Gjj2DBArjvPujRo/DXTJwIl14KO+wABxwAzzwDq1YlpVxJkiQp5QycJEmSJEkqRLNmIUiaMAFmzIAbb4Rddil4flZWCKpOPz2c93TccfDmm7BpU9JKliRJkpLOwEmSJEmSpGJq1y5soTd7Nnz5JVx8MTRpUvD8DRvCFn1HHAFNm8K558LYsSGUkiRJkioSAydJkiRJkkooEoE994SHHoJffoH334chQ6B27YJfs2IFPP449OsHrVvD1VfD1KlJK1mSJElKKAMnSZIkSZK2QUYGHHQQPPssLF4ML74Ihx4a+gsyfz784x/QpQt06gR33gnz5iWvZkmSJKm0GThJkiRJklRKataEE06At9+GhQvhkUdgn30Kf82338K114ZVT337wqOPwvLlSSlXkiRJKjUGTpIkSZIkJUCjRnDeeTBuHPz0E9x+O+y+e+GvGTcOzj8fmjWDww6Dl1+GdeuSU68kSZK0LQycJEmSJElKsNatwyqmadNgyhS48kpo0aLg+Zs3h1VSJ5wA228Pp50GI0bAli3JqliSJEkqGQMnSZIkSZKSJBIJ5zb94x/hzKbRo+Hss6F+/YJfs2ZNOB/qwANDSHXJJTB+PESjyapakiRJKpqBkyRJkiRJKZCWBv36weOPw6JF8MYbcMwxUK1awa9ZvBgeegj23BPatYObb4bZs5NWsiRJklQgAydJkiRJklKsWjU44gh49dUQKj31FAwcGEKpgsyeDbfcAm3bQs+e8MADIbiSJEmSUsHASZIkSZKkMqRePTjjDPjoI1iwAO67D7p3L/w1EyfCpZfCDjvAAQfAM8/A0qXJqVeSJEkCAydJkiRJksqsZs1CkDRxIsyYAX/7G+yyS8Hzs7JCUHX66dCkCXTtCpdfDu+9F86CkiRJkhIlEo16zGhFt2DBAlq2bAnA/PnzadGiRYorkiRJkiTFKxqF8ePh+efhpZeKv5IpIyOc/bT//qHttRdUrZrYWiVJklQ2JSI3MHCqBAycJEmSJKli2rIFRo4M4dMbb8DatcV/bc2asO++OQFU166FnxklSZKkiiMRuUHGNl9BkiRJkiSlREYGHHRQaOvWwVtvwQsvwMcfhx8XZt06+PDD0AAaNoT+/XMCqF13hUgk8e9BkiRJFYMrnCoBVzhJkiRJUuWyaRN89VUInj7+GL78MqyGKomWLWHAgJwAqnnzxNQqSZKk5HNLPcXFwEmSJEmSKrc1a2DcuJwAasqUkl+jffuc8Gm//aBBg9KuUpIkScli4KS4GDhJkiRJknJbtgxGjcoJoObMKdnr09Kge/ecAKpPH6hRIzG1SpIkqfQZOCkuBk6SJEmSpMLMmweffJITQC1aVLLXV6sGe++dE0D16BHOl5IkSVLZZOCkuBg4SZIkSZKKKxqF6dNzwqfRo2HlypJdo25d6NcvJ4DafXeIRBJSriRJkuJg4KS4GDhJkiRJkuK1ZQt8/XVOAPXpp7BxY8musf32MGBATgDVunVCSpUkSVIxGTgpLgZOkiRJkqTSsmEDfP55CJ9GjoSJEyErq2TX2HnnnPBpwABo3DgxtUqSJCl/Bk6Ki4GTJEmSJClRfv8dxozJWQH1/fclv0bnzjkBVN++UKdOqZcpSZKkXAycFBcDJ0mSJElSsixcCJ98khNA/fxzyV6fkQG9esHAgXDggeHrjIzE1CpJklRZGTgpLgZOkiRJkqRUiEbhhx9ywqdPPoHly0t2jfr1c8KnAw+E//3zVpIkSdvAwElxMXCSJEmSJJUFWVkwdWpOADV2LKxdW7Jr7LZbTvjUty/UqJGYWiVJkioyAyfFxcBJkiRJklQWbdoE48fnBFBffgmbNxf/9dWrQ79+OQFUhw4QiSSuXkmSpIrCwElxMXCSJEmSJJUHa9fCuHEwciR8+CF8+23JXt+yZU74NHBg2I5PkiRJeRk4KS4GTpIkSZKk8mjBAhgxIoRPH30EK1YU/7Xp6bDnniF8Ougg6N499EmSJMnASXEycJIkSZIklXeZmTBhQgifPvwQvvoqnAlVXA0bwqBBIXw64ABo3jxxtUqSJJV1Bk6Ki4GTJEmSJKmiWbEiZ+u9Dz8Mq6FKolOnED4deCDssw9Uq5aYOiVJksoiAyfFxcBJkiRJklSRRaPw/fc54dOYMbBxY/FfX7Mm7LdfTgC1664QiSSsXEmSpJQzcFJcDJwkSZIkSZXJunUwdmwInz74AGbMKNnrW7fOCZ8GDIC6dRNSpiRJUsoYOCkuBk6SJEmSpMrs559zwqeRI2HVquK/NiMD9t47hE8HHgh77AFpaYmrVZIkKRkMnBQXAydJkiRJkoItW+Crr0L49OGHMHFi2JKvuBo3hgMOCOHTAQfA9tsnrlZJkqREMXBSXAycJEmSJEnK37Jl8NFHOec/LVpUstfvsUfO6qe994aqVRNTpyRJUmkycFJcDJwkSZIkSSpaNApTp+aET+PGwebNxX997drhzKcDDwxnQO28c+JqlSRJ2hYGToqLgZMkSZIkSSW3Zg2MHp1z/tOcOSV7fcuW0KdPWPnUpw907hzOhJIkSUo1AyfFxcBJkiRJkqRt9+OPOeHTJ5+EQKokataEPffMCaH22gsaNEhMrZIkSYUxcFJcDJwkSZIkSSpdmzbBF1+E8OnDD2Hy5Pius/vuIXzKXgXVpg1EIqVbqyRJ0tYMnBQXAydJkiRJkhJr8WIYMSKETyNGwNKl8V2nceOcAGrvvaFHD6hevXRrlSRJMnBSXAycJEmSJElKnqwsmD4dPv8cPvss/Hf27PiuVaUKdO+eswJq772hadPSrVeSJFU+Bk6Ki4GTJEmSJEmptWRJ2IIvO4SaOBE2bozvWjvtlBM+9ekTtuVLTy/deiVJUsWWiNwgY5uvIEmSJEmSpEI1aQKHHx4ahLBp8uScFVCffRa25SuOn34K7bnnwo/r1IG99soJofbcE+rWTcz7kCRJKogrnCoBVzhJkiRJklS2RaMhRPr885wAatq00F9SaWnQqVPsNnytW0MkUuplS5Kkcsot9RQXAydJkiRJksqfVavgq69yVkF9+SWsXh3ftZo2zQmf9t4bunWDqlVLt15JklR+uKWeJEmSJElSJVG3LgwaFBpAZiZ8+23sKqiffiretRYtgtdeCw2gWjXo2TNnFVTv3tC4cWLehyRJqhwMnCRJkiRJksqB9HTo0iW0888PfQsXwhdf5KyCmjQJNm8u+lobN8Knn4aWrW3bnBVQffpA+/Zhez5JkqTicEu9SsAt9SRJkiRJqhzWrw+hU/YKqM8/h2XL4rtW7drQpg3ssktoub9u0SIEYJIkqXxySz1JkiRJkiQVqEYN2Gef0ACiUZgzJyd8+vxz+O674l1rzRqYMiW0rVWtCq1bx4ZQ2W2nnaB69VJ6Q5IkqdwwcJIkSZIkSaqgIhHYddfQTj899K1YAV9+mbMK6quvYN26kl130yaYNSu0/O7ZokXeICq71a+/re9KkiSVRQZOkiRJkiRJlUiDBnDwwaEBbNkCU6fGroL6+ef4rx+Nwvz5oY0enXd8u+1iA6jcq6SaNg2BlSRJKn8MnCRJkiRJkiqxjAzo1i20iy8Ofb/8AjNmwA8/hDZnTs7Xa9Zs2/2WLw9t/Pi8YzVrws475w2idtkFdtwx1CpJksomv01LkiRJkiQpxg47hLb//rH90SgsXZo3hMpuS5Zs233XrYNvvw1ta+np4dyo/Lbp23lnqFVr2+4tSZK2jYGTJEmSJEmSiiUSgSZNQuvdO+/46tV5Q6jscGr+fMjKiv/emZk518tPs2Z5t+rr3j2cX+U2fZIkJZ6BkyRJkiRJkkpFnTrQtWtoW9u0CebOzX+bvh9/hI0bt+3eCxeG9umnsf077ggHHhja/vtDvXrbdh9JkpQ/AydJkiRJkiQlXNWq0LZtaFvLyoJff81/m745c2DlyvjvO28ePP54aOnpsNdeOQFU9+6hT5IkbbtINBqNproIJdaCBQto2bIlAPPnz6dFixYprkiSJEmSJKl4olH47beCt+pbuDD+azdsCIMG5QRQzZuXXt2SJJVlicgNXOEkSZIkSZKkMisSge22C61Xr7zj69aFLfm23qpv6lRYtKjwa//2G7z8cmgAHTvmhE/77gvVq5f++5EkqaIycJIkSZIkSVK5VbNmCIo6doztj0bh22/hww9DGzs2nCNVmG+/De3ee6FGDejXLyeAat8+hF+SJCl/bqlXCbilniRJkiRJquzWrYMxY+CDD0IANXNmyV7fqhUccEAInwYOhPr1E1KmJElJkYjcwMCpEjBwkiRJkiRJijVvXs7qp48/hpUri//atDTYc8+c1U89e0J6euJqlSSptBk4KS4GTpIkSZIkSQXbsgW++iongJowIWzJV1wNGoRVT9kBlI9eJEllnYGT4mLgJEmSJEmSVHzLl8PIkTkB1K+/luz1u+2WEz717RvOg5IkqSwxcFJcDJwkSZIkSZLiE43Cd9/lhE9jx8LGjcV/ffXqIXTKDqB22w0ikcTVK0lScRg4KS4GTpIkSZIkSaVj3boQOmUHUNOnl+z1LVrAAQeE8GngQGjYMDF1SpJUGAMnxcXASZIkSZIkKTHmz88Jn0aOhN9/L/5r09KgZ8+c1U+9ekFGRsJKlSTpDwZOiouBkyRJkiRJUuJt2QITJuQEUOPHQ1ZW8V9fvz7sv39OANWqVcJKlSRVcgZOiouBkyRJkiRJUvL99ht8/HFOALVgQcle364ddOkC7duHr9u3h7ZtoXbtxNQrSao8EpEbuEhXkiRJkiRJSoCGDeHYY0OLRsN5T9nh05gxsGFD4a+fOTO0rbVsGcKn3EFU+/bQvDlEIol5L5IkFcXASZIkSZIkSUqwSAR22y20Sy+F9eth3LicAOq774p/rfnzQ/voo9j+2rXzhlDt20ObNlC9eum+H0mStuaWepWAW+pJkiRJkiSVbQsWwIgRIXz66CNYsaL0rp2WBq1bx4ZQ2a1RI1dFSVJl5BlOiouBkyRJkiRJUvmRmQmTJsHkyTBjRk6bNy9szVeaGjTIG0K1awc77wxVqpTuvSRJZYdnOEmSJEmSJEkVXHo69OoVWm7r18Ps2bEh1IwZ4Zyndeviu9eKFfDFF6HllpERtuLbOohq3x7q14/vXpKkis3ASZIkSZIkSSoHatSAzp1Dyy0rC375JW8INWNG6I/Hli0519ra9tvnDaHat4dWrUJYJkmqnAycJEmSJEmSpHIsLQ1atgxt0KDYsdWrc8Kn7P/OmAGzZsGmTfHdb/Hi0MaMie2vXh3ato0Nobp0gQ4dQo2SpIrNwEmSJEmSJEmqoOrUgR49QsstMxPmzo0NobLb0qXx3WvDBpg6NbTcGjWC/fbLabvtBpFIfPeQJJVdBk6SJEmSJElSJZOeDrvsEtqf/hQ79ttvsUFU9tdz5oSgqqSWLYP//jc0gMaNQ/DUv3/4b/v2BlCSVBEYOEmSJEmSJEn6Q8OG0Lt3aLlt2gQ//pg3iJo+HVauLP71ly6FV18NDcKZULkDqLZtDaAkqTwycJIkSZIkSZJUpKpVc85myi0ahSVL8p4TNW0aLFhQ9HUXL4aXXw4NoFmz2ACqTRsDKEkqDwycJEmSJEmSJMUtEgmrlLbfHvr1y+mPRsM5UaNHw6hRoRUngFq4EF58MTSAHXaIDaB23tkASpLKokg0Go2muggl1oIFC2jZsiUA8+fPp0WLFimuSJIkSZIkSZVNNAo//RSCp+wQ6pdfSn6dli1D8JQdQrVubQAlSSWViNwgbZuvUAHMmzePyy+/nPbt21OrVi0aNmxIz549ufvuu1m3bl1C7rlu3Tp23nlnIpEIkUiE1q1bJ+Q+kiRJkiRJUlkQiYTVSWedBcOGwfz5MHs2PP44nHRS2EqvOObPD68/66xwvdat4fTT4emnYd68BL4BSVKhKv0Kp7fffptTTjmFVatW5Tvetm1b3n33Xdq0aVOq973iiiu49957//jxjjvuyNy5c0v1Htlc4SRJkiRJkqSyLhoNAVT26qfRo2HRopJfp3XrnO33+vcPK6IkSbESkRtU6sBp8uTJ9OnTh/Xr11O7dm2uvfZa+vfvz/r163nppZf4z3/+A4TQaeLEidSpU6fU7tuzZ0+qVKlClSpVWL16tYGTJEmSJEmSlEs0CjNnxgZQS5aU/Do77xx7BpSPxiQpMblBxjZfoRy75JJLWL9+PRkZGYwYMYLevXv/MTZgwAB23XVXrrrqKmbNmsW9997LzTffvM33zMzM5OyzzyYzM5ObbrqJJ598ktWrV2/zdSVJkiRJkqSKJBKB9u1DO++8EEBNnx6Cp+y2dGnR1/nxx9Ceeir8uE2b2ACqefOEvQVJqlQq7Qqn8ePHs+eeewJw7rnn8uijj+aZk5WVRceOHZk+fTr169dnyZIlVKlSZZvue99993H55ZfTrl07pk6dStu2bZk3b54rnCRJkiRJkqQSiEbh++9zVj+NHg3Ll5f8Om3b5gRQ/foV/ywpSSrPEpEbpG3zFcqp4cOH//H1GWecke+ctLQ0Tj31VAB+//13Ro0atU33nDdvHjfeeCMAjz76KFWrVt2m60mSJEmSJEmVVSQCu+8OF10E//1v2G5v6lR46CE48kho2LB415k1Cx5/HE48Max26tABzj8fXn4ZFi9O7HuQpIqk0m6p9+mnnwJQq1YtunfvXuC8fv36/fH1Z599xgEHHBD3PS+44ALWrl3LkCFD2G+//eK+jiRJkiRJkqRYaWnQqVNoF18MWVkwbVrO6qcxY2DFiqKvM2NGaNkbIrVqBV265LSuXcO5UGmV9qP8kpS/Shs4TZ8+HYA2bdqQkVHwT0P79u3zvCYeL730Eu+99x4NGjTg3nvvjfs6+VmwYEGh4wsXLizV+0mSJEmSJEllXVpaTkh0ySWQmRkCqOwt+MaMgZUri77Ozz+H9vbbOX21a4dgKzuA6tIl/LhWrUS9G0kq+ypl4LRhwwaWLVsGUOS+hA0aNKBWrVqsXbuW+fPnx3W/FStW8Ne//hWAO++8k8aNG8d1nYJk77MoSZIkSZIkKX/p6SEc6toVLr00BFDffJMTQI0dC6tWFe9aa9bAF1+Eli0SgTZtYkOoLl2gRYswJkkVXaUMnFavXv3H17Vr1y5yfnbgtGbNmrjud+WVV7J48WJ69+7N2WefHdc1JEmSJEmSJJWe9HTo1i20yy8PAdTkySF8GjUKxo2DXI8RixSNwuzZof33vzn9DRrkDaF22w2qVSvtdyRJqVUpA6cNGzb88XXVqlWLnF/tf3/6r1+/vsT3Gjt2LE899RQZGRk8+uijRBLwcYaiVl4tXLiQXr16lfp9JUmSJEmSpIoiPR169Ajtiitgy5ZwltOUKWElVHZbsqRk112xIuccqWwZGdC+fWwI1aULNGlSeu9HkpKtUgZO1atX/+PrTZs2FTl/48aNANSoUaNE99m4cSPnnHMO0WiUSy65hM6dO5es0GIqaltASZIkSZIkSSWTkQEdO4Z2yik5/YsW5Q2hZsyArKziX3vLFvj229Ceey6nv2nTvKuh2rYNtUhSWVcp/6iqU6fOH18XZ5u8tWvXAsXbfi+32267jZkzZ9KyZUtuueWWkhUpSZIkSZIkqcxp2hQOOii0bOvXw3ffxYZQ33wDK1eW7NqLFoX24Yc5fdWrw+67x4ZQnTtD/fql8W4kqfRUysCpevXqbLfddixfvpwFCxYUOnfFihV/BE4tW7Ys0X3uuusuAAYOHMjbb7+d75zsa69du5aXXnoJgCZNmjBgwIAS3UuSJEmSJElSatSokbMdX7ZoFObNiw2gpkyBH38s2bU3bIBJk0LLbccd827Jt9NOkJa2re9GkuJTKQMngN12241x48YxZ84ctmzZQkYB61JnzJjxx9cdOnQo0T2yt+sbOnQoQ4cOLXTusmXLOPHEEwHo16+fgZMkSZIkSZJUjkUi0Lp1aIcfntO/ahVMmxYbQk2bFlZJlcS8eaG9+WZOX506YfVT7hCqUyeoWbMU3pAkFaHSBk777LMP48aNY+3atUyaNIk999wz33ljxoz54+s+ffokqzxJkiRJkiRJFVDdutCnT2jZMjNhzpzYEOqbb+CXX0p27dWr4bPPQsuWkQG9e8OgQaH16OGZUJISIxKNRqOpLiIVxo8f/0fIdO655/Loo4/mmZOVlUXHjh2ZPn069evXZ8mSJVSpUqVU62jdujXz5s1jxx13/P/27j3Ky6rQH/97kDuoaECCoKhEaiiiQKKiIWqZmKJpWSaipmlalqfjpfPNLueU2TJ1uTyGV+KcPJikFWInpSOTFwxJvKUpCpiAKeAFlEEYmN8fn998mHGG62eGDzCv11p78cyzn2d/9lNru2fmPXs/mTt3bpO2XWvevHnF7QBfe+219OrVq1k+BwAAAABoOosWJc88Uz+Eev75ZOXKTW9zxx2T4cML4dNRRyUf+1hhNRbQsjRHbtBid/QcMmRIhg0bliS57bbbMm3atAbXXHPNNXnhhReSJN/85jcbhE1Tp05NRUVFKioqcuaZZzZ7nwEAAACAlqNr1+TII5NvfSv55S8LodN77xWCp/Hjk29/OxkxonDdhnr33eS3v02+/vXk4x8vbPl3zjnJhAnJwoXN9CBAi9CiF09ef/31OfTQQ1NVVZVjjjkmV1xxRYYPH56qqqpMmDAhN998c5KkX79+ueSSS8rcWwAAAACgpWvbtvCepv33T77ylcK5mprk9dfrr4R6+unkpZeS1avX3d4//pHcdluhJMnAgWtWPx12WNKhQ7M+DrANadGB08CBA3PXXXfl9NNPz5IlS3LFFVc0uKZfv36ZPHlytt9++zL0EAAAAABg3Soqkp49C+XYY9ecf++95M9/Th58sFD+9rf1tzVzZqFcfXXSrl0ybFghfDr66OSAA5JWLXbPLGB9Wvx/Ho4//vg888wz+da3vpV+/fqlY8eO6dKlSwYNGpSf/vSnmTlzZvr27VvubgIAAAAAbJTOnZPPfja59trkueeS+fMLW/F95StJjx7rv/+DD5IpU5LLLksOOijp3j35wheSW29NXn21+fsPbF0qampqasrdCZpXc7z8CwAAAADYetXUJM8/v2b1U2Vl8v77G9fGxz62ZvXT8OFJly7N0lWgGTRHbiBwagEETgAAAADAuqxYkTz+eCF8mjIlmT59/e9/qqtVq2TIkDUB1MEHF943BWyZBE5sEoETAAAAALAx3nkneeihNQHUrFkbd3+nTskRRxTCp6OPTvbdt/CuKWDL0By5QeuSWwAAAAAAYJvSpUsyalShJIV3NtVuv/enPyWLF6/7/vffT+6/v1CSwjujalc/HXXUhr1DCti6WOHUAljhBAAAAAA0ldWrk6eeWrP66eGHkw8+2Lg2PvGJNaufDj886dy5WboKrIUt9dgkAicAAAAAoLlUVSWPPLImgJo5c+Pub9MmGTp0zeqnQYOS1vbmgmYlcGKTCJwAAAAAgM1l4cLCtntTphRCqH/8Y+Pu33HH5Mgj12zB17ev9z9BUxM4sUkETgAAAABAOdTUJLNmrQmf/u//kiVLNq6NHXZI9twz2WuvNaX26969rYaCTdEcuYGhCAAAAABAs6ioSPr1K5QLLkiqq5MnnlgTQE2bVji3LkuWFN4Z9dRTDetat0769KkfQtUNpTp1aoaHAholcAIAAAAAYLNo3brwvqahQ5P/9/+SpUuTyso1AdTzz29ce9XVycsvF0pjPvrRhquiakv37rbqg6YkcAIAAAAAoCy23z4ZObJQkmT+/ML7nx58sBBC/fOfpbX/xhuF8thjDes6daofQtU93n33pE2b0j4bWhqBEwAAAAAAW4Rdd03OOKNQamqSuXOTV15JZs8u/Fu3LF1a2me9/37y7LOF8mGtWiW77VZ/RVTdUGqHHUr7bNgWCZwAAAAAANjiVFQke+xRKB9WU5MsXlw/gKobSi1YUNpnr15dCLvmzi2suPqwrl3X/t6oHj0KgRW0NAInAAAAAAC2KhUVhdCna9fkk59sWL9sWTJnTsOVUbNnF86vWFHa5y9aVCh/+UvDuvbt1wRRe+6ZfOxjyX77Jfvvn3TpUtrnwpZM4AQAAAAAwDalY8fkE58olA9btarwrqi1bdX3zjulffby5cnzzxfKh+2+ezJgwJqy//6FYMqKKLYFAicAAAAAAFqM7bYrvJ9pt92S4cMb1r/99tq36ps3r7Cd36Z69dVC+f3v15zr1KmwAqpuELXffsn222/650A5CJwAAAAAAOD/t9NOyaBBhfJhy5cX3uvU2FZ9s2cX6jfW++8njz9eKHXttVf9lVADBiR9+hS2E4QtkcAJAAAAAAA2QPv2yd57F8qHrV6dvP56w1VRf/tb8sILycqVG/dZtfffc8+aczvssCZ8qi39+xe2EIRyEzgBAAAAAECJWrVKdt21UA4/vH7dihWF0Onpp5Nnnin8+/TTycKFG/cZS5YkjzxSKHU/92Mfq78SasCApFcvq6HYvAROAAAAAADQjNq2XRME1aqpSf75zzXhU2158cVk1aoNb3v16sI9L76Y/PrXa87vvHPD1VD77ltYpQXNQeAEAAAAAACbWUVF0qNHoXzmM2vOL1+ePP98wyDq7bc3rv233kqmTi2UWtttV9gO8MNB1C67WA1F6QROAAAAAACwhWjfPjnwwEKpVVOTzJvXcEu+l14q1G2oVasK75T629+S//mfNee7dasfQA0YUAim2rZtuudi2ydwAgAAAACALVhFRdK7d6GMHLnm/LJlyXPP1V8J9cwzhXc9bYyFC5MpUwqlVps2yT77FMKngQOTwYML/3bq1DTPxLZH4AQAAAAAAFuhjh2TIUMKpVZNTTJ3bv2VUE8/nbzyysa1vXJloY1nnkn+678K51q1KoRQgwYVyuDBhUDKe6FIBE4AAAAAALDNqKhI9tijUE44Yc35pUuTZ5+tvxLqmWeS99/f8LZXr16zJd8vf1k417p10r9//RCqf3/b8bVEAicAAAAAANjGbb99csghhVJr9epk9uz6K6Gefjp59dUNb7e6OnnqqUK59dbCubZtCyuf6oZQ++xTCKfYdvm/FwAAAAAAWqBWrZK+fQvl5JPXnH/nnTWroWbOTP7618K7olat2rB2V6xInniiUGp16FB4B1TdEKpfv0If2DYInAAAAAAAgKIuXZJhwwqlVlVVIYCaMaMQJM2YkbzwQuGdURuiqip57LFCqbX99smBB9YPofbcs7AtIFsfgRMAAAAAALBOHTokBx9cKLXee6+wAqpuCDVr1oa3uXRpUllZKLW6dFkTQNWGUL17C6G2BgInAAAAAABgo3Xu3HAl1DvvJE8+uSaAmjEjmTt3w9t8551kypRCqdWtW8MQqkePJnoImozACQAAAAAAaBJduiRHHlkotRYtKrwHqm4INX/+hre5cGHyhz8USq2ePeuHUIMGFYIpyqeipmZDd1hkazVv3rz07t07SfLaa6+lV69eZe4RAAAAAAAt2euv1w+hnniiECyVYvfd6wdQBx2U7LRT0/R3W9McuYEVTgAAAAAAwGbVo0cycmShJElNTTJvXv33Qc2Ykbz99oa3+eqrhfKb36w517fvmgBq2LBkyJCmfQ7WEDgBAAAAAABlVVGR9O5dKKNGFc7V1CRz5tQPof7612Tp0g1v9+WXC2XChOTzn0/uvrt5+o/ACQAAAAAA2AJVVCR77lkop55aOLd6dTJrVv0Q6sknk6qq9bc3aFDz9relEzgBAAAAAABbhVatko9/vFC+/OXCuerq5O9/rx9CPfVUsmJF/XsFTs1L4AQAAAAAAGy1WrdO+vcvlDPPLJxbsSL529/qh1AHHljWbm7zBE4AAAAAAMA2pW3bZODAQvnqV8vdm5ahVbk7AAAAAAAAwNZN4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJSkdbk7QPOrrq4uHr/++utl7AkAAAAAAFBudbOCuhlCKQROLcDChQuLx0OGDCljTwAAAAAAgC3JwoUL06dPn5LbsaUeAAAAAAAAJamoqampKXcnaF7Lly/Ps88+myTp1q1bWre2sC0pLBmsXfE1ffr09OjRo8w9AjaFsQzbBmMZtg3GMmwbjGXYNhjLsG1orrFcXV1d3B1tv/32S/v27UtuU/LQArRv3z6DBw8udze2aD169EivXr3K3Q2gRMYybBuMZdg2GMuwbTCWYdtgLMO2oanHclNso1eXLfUAAAAAAAAoicAJAAAAAACAkgicAAAAAAAAKInACQAAAAAAgJIInAAAAAAAACiJwAkAAAAAAICSCJwAAAAAAAAoSUVNTU1NuTsBAAAAAADA1ssKJwAAAAAAAEoicAIAAAAAAKAkAicAAAAAAABKInACAAAAAACgJAInAAAAAAAASiJwAgAAAAAAoCQCJwAAAAAAAEoicAIAAAAAAKAkAicAAAAAAABKInACAAAAAACgJAInWqRXX301l1xySfbee+906tQpO++8cwYPHpyf/exnWbZsWbm7B6xHRUXFBpVPfepT5e4qtEhvvvlm7rvvvnzve9/Lsccem65duxbH5ZlnnrnR7f3hD3/IqFGj0qtXr7Rr1y69evXKqFGj8oc//KHpOw8UNcVYHjdu3AbP2+PGjWvW54GWasaMGfnhD3+YY445pjiXdu7cOf369cuYMWPyyCOPbFR75mUoj6YYy+ZlKK8lS5ZkwoQJueSSS3LEEUekb9++2XHHHdO2bdt07949n/rUp3L11Vdn8eLFG9TeY489ltNPPz2777572rdvn1122SWf/vSn8z//8z/N/CRr17psnwxlMmnSpJx++ulZsmRJ8dyyZcsyY8aMzJgxI7feemsmT56cvn37lrGXALD1+uhHP9ok7axevTrnnntubrvttnrn58+fn/nz5+e3v/1tzjnnnIwdOzatWvk7KmhqTTWWgfI5/PDD8/DDDzc4v2LFisyaNSuzZs3KuHHjcsYZZ+SWW25J27Zt19qWeRnKpynHMlA+06dPz2mnndZo3cKFC1NZWZnKysr87Gc/y3//93/n05/+9Frb+v73v58f/ehHWb16dfHcG2+8kQceeCAPPPBAfvWrX2XixIlp3759kz/HugicaFFmzpyZL3zhC6mqqkrnzp1z+eWXZ/jw4amqqsqECRNyyy235KWXXspxxx2XGTNmZPvtty93l4F1OP/883PBBRestb5Tp06bsTdAY3bbbbfsvffeeeCBBzb63u9+97vFX2oNHDgw//qv/5q99torr7zySq6++urMnDkzt956a7p165Yf//jHTd11oI5SxnKtP/7xj+nZs+da63v16rXJbQONW7BgQZKkZ8+eOeWUUzJs2LDstttuWbVqVaZNm5Zrrrkm8+fPz/jx47Ny5crceeeda23LvAzl05RjuZZ5Gcqjd+/eGT58eA466KD07t07PXr0yOrVqzNv3rxMnDgx99xzTxYtWpTPfe5zmT59egYMGNCgjbFjx+YHP/hBkmSvvfbKFVdckf322y8LFizI9ddfn4ceeiiTJ0/OWWedtUH/PWhSNdCCDBs2rCZJTevWrWsee+yxBvVXX311TZKaJDVXXnnl5u8gsEGMU9iyfe9736uZNGlSzT//+c+ampqamjlz5hTH7ejRozeojRdffLGmdevWNUlqBg0aVLNs2bJ69e+//37NoEGDivP6rFmzmvoxoMVrirF8xx13FO+ZM2dO83UWaNRxxx1Xc9ddd9VUV1c3Wr9w4cKafv36FcdpZWVlo9eZl6G8mmosm5ehvNY2huu69957i+N01KhRDeoXL15cs+OOO9Ykqdltt91qFi5c2OAzjj/++GIbDz30UFN1f4NY40yLMX369OLy47PPPjtDhw5tcM0ll1ySffbZJ0ly/fXXZ+XKlZu1jwCwLfjBD36QkSNHlrQd13XXXZfq6uokyQ033JAOHTrUq+/YsWNuuOGGJEl1dXWuvfbaTe8w0KimGMtAed1333059dRTs9122zVa37Vr11xzzTXFrydOnNjodeZlKK+mGstAea1tDNd14okn5uMf/3iSNLqV5q233pp33303SfLTn/40Xbt2bfAZ//mf/1n8rJ/97GeldnujCJxoMX77298Wj8eMGdPoNa1atcoZZ5yRJHnnnXfy0EMPbY6uAQB11NTU5He/+12SZO+9987BBx/c6HUHH3xw8Rvx3/3ud6mpqdlsfQSAbcXw4cOLx6+88kqDevMybB3WN5aBrUfta16WL1/eoK72d9w77LBDTjrppEbv79WrV4466qgkyZ/+9KcsXbq0eTraCIETLcYjjzySpPBOl4MOOmit1x1xxBHF40cffbTZ+wUA1DdnzpziPvV15+XG1NbPnz8/c+fObe6uAcA254MPPigeN/aX1+Zl2DqsbywDW4cXX3wxTz31VJLCH3rUtWLFikyfPj1JMnTo0LRt23at7dTOyR988EFmzJjRPJ1thMCJFuOFF15IkvTt2zetW7de63V1B3LtPcCW6e67786+++6bjh07Zvvtt8/HPvaxjB492upE2Mo9//zzxeMPf4P9YeZt2HqMGTMmPXv2TNu2bdO1a9ccfPDB+bd/+7fMnz+/3F2DFq2ysrJ4XLvFfF3mZdg6rG8sf5h5GbYcy5Yty6xZs/Lzn/88RxxxRHEb24svvrjedS+99FJWrVqVZMudkwVOtAjLly/PokWLkhSWFK7LTjvtlE6dOiVJXnvttWbvG7Dpnn/++bzwwgupqqrKe++9l5dffjnjx4/PkUcemVGjRhX3tAW2LvPmzSser2/e7t27d/HYvA1btqlTp+b111/PypUrs3jx4vzlL3/Jf/zHf6Rv374ZO3ZsubsHLdLq1atz1VVXFb8+9dRTG1xjXoYt34aM5Q8zL0N5jRs3LhUVFamoqEinTp3Sr1+/XHLJJXnjjTeSJJdddlm+9KUv1btna5iT177MA7Yhdfep7Ny583qv79SpU95///289957zdktYBN17Ngxn/vc5zJixIjsvffe6dy5cxYuXJjKysr84he/yOLFi/Pb3/42J5xwQh588MG0adOm3F0GNsLGzNu1fySSxLwNW6g999wzJ510UoYOHVr8wXf27Nn5zW9+k4kTJ2b58uX52te+loqKipx77rll7i20LNdee21xa56TTjqp0e3nzcuw5duQsVzLvAxbtgMOOCA333xzBg8e3KBua5iTBU60CHVfsLauvS1rtWvXLklSVVXVbH0CNt38+fPTpUuXBuePPvroXHTRRTn22GMzc+bMVFZW5qabbso3vvGNzd9JYJNtzLxdO2cn5m3YEo0aNSqjR49ORUVFvfODBw/OF77whdx333056aSTsnLlynzrW9/K5z73ueyyyy5l6i20LJWVlbnsssuSJN27d89NN93U6HXmZdiybehYTszLsCU58cQTM2jQoCSFOfOVV17Jr3/969x777057bTTct1112XkyJH17tka5mRb6tEitG/fvni8YsWK9V5f+6LFDh06NFufgE3XWNhU66Mf/WgmTpxYXNV0ww03bKZeAU1lY+btui9HNm/DlmfHHXds8EutukaOHJnvfe97SQp71992222bq2vQov3tb3/LqFGjUl1dnfbt2+fuu+9O9+7dG73WvAxbro0Zy4l5GbYkXbp0Sf/+/dO/f/8MHjw4X/ziF3PPPfdk/PjxmT17dk444YSMGzeu3j1bw5wscKJF2H777YvHG7KE8P3330+yYdvvAVuePffcM0cffXSS5OWXX86CBQvK3CNgY2zMvF07ZyfmbdhanXvuucVfftV94TnQPObMmZNjjjkmb7/9drbbbrtMmDAhhx9++FqvNy/Dlmljx/KGMi9DeX3lK1/JKaecktWrV+fCCy/MW2+9VazbGuZkgRMtQvv27fORj3wkSf2XqzXm7bffLg7Iui9XA7Yu++67b/F4/vz5ZewJsLHqvvx0ffN23Zefmrdh69S9e/fi9+rmbGheCxYsyFFHHZUFCxakoqIit99+e0444YR13mNehi3PpozlDWVehvKrHc/vv/9+/vd//7d4fmuYkwVOtBi1v3x++eWXU11dvdbr/v73vxeP99lnn2bvF9A81rVNALBlqxsY152XG2Pehm2DeRua36JFi3L00Udn9uzZSQpbT59xxhnrvc+8DFuWTR3LG8O8DOXVrVu34vGrr75aPO7Xr1+22267JFvunCxwosU47LDDkhSS4b/+9a9rva7ucuFDDz202fsFNI/nn3++eNyzZ88y9gTYWHvssUdx3K5vG48///nPSZJdd901ffr0ae6uAc1g4cKFWbRoURJzNjSXd999N5/+9KeL3yNfddVV+frXv75B95qXYctRyljeUOZlKL+6qwvrbofXtm3bDBkyJEkybdq0db7HqXbObteuXQYNGtRMPW1I4ESLceKJJxaP77jjjkavWb16dcaPH5+k8OK24cOHb46uAU1szpw5efDBB5Mke+21V3bdddcy9wjYGBUVFcUtBP7+97/n8ccfb/S6xx9/vPhXWyeccIK/xISt1M0335yampokyRFHHFHm3sC2Z9myZTnuuOPy5JNPJkm++93v5tJLL93g+83LsGUodSxvKPMylN/dd99dPN5vv/3q1dX+jnvJkiW55557Gr1/3rx5mTJlSpJkxIgR9d791NwETrQYQ4YMybBhw5Ikt912W6ZNm9bgmmuuuSYvvPBCkuSb3/xm2rRps1n7CKzfpEmT1rkt5htvvJGTTz65+FceF1xwwebqGtCELr744uJWARdddFGqqqrq1VdVVeWiiy5KkrRu3ToXX3zx5u4isB5z587NzJkz13nNfffdlx/+8IdJkg4dOmTMmDGbo2vQYqxYsSKjRo3Ko48+mqTwc+6///u/b3Q75mUor6YYy+ZlKL9x48Zl+fLl67zm2muvzf3335+ksMq49vfZtc4555zsuOOOSZLLLrssixcvrle/atWqXHDBBVm1alWS5Dvf+U5TdX+DVNTURtbQAsycOTOHHnpoqqqq0rlz51xxxRUZPnx4qqqqMmHChNx8881JCvthzpgxY7Omv8CG6dOnT1auXJmTTz45Q4cOTZ8+fdKhQ4csWrQoU6dOzdixY4vL/w877LBMmTIl7dq1K3OvoWV55JFH8vLLLxe/XrRoUfGb3EMPPTTnnHNOvevPPPPMRtu5/PLLc9VVVyVJBg4cmEsvvTR77bVXXnnllfz0pz8t/sB8+eWX58c//nEzPAm0bKWO5alTp2b48OEZOnRojj/++AwYMCDdu3dPksyePTsTJ07MxIkTi39FfeONN/pDEWhiJ598cvGvn4888shcd91161x51LZt2/Tr16/ROvMylE9TjGXzMpRfnz5991qLNgAADdxJREFUsnTp0px88sk57LDDstdee6Vz585ZunRpnn322fzqV78qBstt27bN5MmTc9RRRzVoZ+zYsfna176WpLCzz3e/+93st99+WbBgQa677ro89NBDSZLTTjstd9555+Z7wAicaIEmTZqU008/PUuWLGm0vl+/fpk8eXL69u27mXsGbIg+ffrUe2Hi2px88sm59dZb06VLl+bvFFDPmWeemV/+8pcbfP3avh1dvXp1vvrVr+b2229f671nn312br755rRqZeE+NLVSx3LtL7bWp2PHjrn22mtz7rnnbnQfgXXb2G3tdt9998ydO7fROvMylE9TjGXzMpTfhv5Oq1evXrn99ttz9NFHr/WaK6+8Mj/60Y/W+vP0Zz/72fzmN79J+/btN7m/m0LgRIv06quv5vrrr8/kyZMzb968tG3bNn379s0pp5ySCy+8MB07dix3F4G1qKysTGVlZaZNm5bZs2dn0aJFWbJkSTp37pzevXvnkEMOyejRozN06NBydxVarKYKnGrdf//9ufnmm/PEE09k0aJF6dq1awYPHpzzzjsvxx57bKndBdai1LG8dOnS/P73v8+0adMyY8aMvP7661m0aFGqq6uz00475ROf+ERGjBiRc845p/gX1kDTasrAqZZ5GTa/phjL5mUovxdffDGTJ0/Oo48+mpdffjlvvPFGFi9enA4dOqR79+454IADMnLkyJx66qkb9Pvpxx57LDfeeGMefvjhvPHGG+nSpUsGDBiQMWPG5LTTTtsMT9SQwAkAAAAAAICSWOMMAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAABssrlz56aioiIVFRUZN25cubsDAACUicAJAABgE0ydOrUYtGxoufjii8vdbQAAgGYhcAIAAAAAAKAkrcvdAQAAgK3d+eefnwsuuGC913Xt2nUz9AYAAGDzEzgBAACUqHv37unfv3+5uwEAAFA2ttQDAAAAAACgJAInAACAMunTp08qKipy5plnJkmeeOKJnHbaaendu3fat2+f3r17Z8yYMfn73/++Qe1NmjQpn//859OrV6+0a9cuH/nIRzJ06NBcddVVee+99zaojeeeey4XXXRR9ttvv+y0005p06ZNdtlllxx11FG5+uqr8/rrr6+3jQcffDDHH398dtlll7Rr1y577LFHzj///MybN2+d9y1YsCCXXXZZDjzwwOy4445p06ZNPvrRj2a//fbLaaedlnHjxmXJkiUb9BwAAMDmVVFTU1NT7k4AAABsbaZOnZrhw4cnSa688sp8//vf3+g2+vTpk1dffTWjR4/O4YcfnvPOOy/V1dUNrmvXrl3+67/+K6ecckqj7Sxfvjxf+tKXcu+99671s3r27JnJkyfngAMOaLR+1apV+c53vpPrrrsu6/oxcfTo0Rk3blzx67lz52aPPfZIktxxxx158cUXc9VVVzV6b7du3VJZWZl99tmnQd3DDz+ckSNHrjdQmjRpUkaOHLnOawAAgM3PO5wAAADK7Kmnnsqdd96Z7t275/LLL8+QIUOyfPny3H///bnuuuvywQcf5Mtf/nL22GOPDBo0qMH9o0ePLoZNAwYMyCWXXJJ99tknb731ViZMmJBx48ZlwYIFGTFiRJ555pnsuuuuDdo499xzc/vttydJevTokQsvvDCHHHJIdtxxxyxcuDDTp0/PxIkT1/kct9xySx577LEcccQROe+889KvX7+88847GT9+fMaPH5+FCxfmrLPOyrRp0+rd98EHH+SLX/xilixZku233z7nn39+hg8fnu7du2fFihWZM2dOHnvssXUGagAAQHlZ4QQAALAJ6q5wOv/883PBBRes956Pf/zjadOmTfHr2hVOSbL77rvn8ccfzy677FLvnoceeijHHHNMqqurM3jw4EyfPr1e/eTJk4srfkaMGJH7778/bdu2rXfNLbfcknPPPTdJcuqpp+auu+6qV//73/8+J5xwQpJk6NChuf/++9OlS5dGn+G1115L7969i1/XXeGUJF/96lczduzYVFRU1Lvvq1/9am699dYkyZNPPpmBAwcW6/7v//4vI0aMSLLuFUzV1dVZtmxZdthhh0brAQCA8hE4AQAAbIK6gdOGmjNnTvr06VP8um7gNHHixJx88smN3nfBBRfkpptuSlJ4z1PdVU6f/exn84c//CFt2rTJK6+8Ui8Mquvoo4/OlClT0rp16/zjH/9Ijx49inWHHHJIpk2blo4dO2bWrFnp2bPnBj9T3cCpR48emTNnTtq1a9fguhdffDF77713kuT666/PN77xjWLdnXfemS9/+ctJknfffVegBAAAW6FW5e4AAABAS7fTTjsVVxg15qyzzioeT5kypXhcXV2dysrKJMkxxxyz1rApKawwqr1n6tSpxfOLFy/O448/niT5whe+sFFh04d9/vOfbzRsSgqruzp37pwkmT17dr26uuHXHXfcscmfDwAAlI/ACQAAoERXXnllampq1lvqrm6qa+DAgWndeu2v2D3ggAOK2+Q9++yzxfOzZ8/OsmXLkiSf/OQn19nHuvXPPfdc8fipp55K7cYXw4YNW/eDrkftCqa12WmnnZIkS5curXf+sMMOy5577pkkufjiizNkyJD85Cc/yaOPPpoVK1aU1CcAAGDzEDgBAACUWffu3ddZ37p16+y8885Jkrfeeqt4vu7x+tqo+26ouvctWrSoeFx3pdGm6Nix4zrrW7Uq/Ai6atWqeufbtGmTSZMmZZ999klS2DbwiiuuyGGHHZYuXbrkM5/5TO68884G9wEAAFsOgRMAAECZVVRUbBFtlNO+++6bZ599Nvfee2/OOuus9O3bN0lSVVWVP/7xj/nyl7+cT37yk3nzzTfL3FMAAKAxAicAAIAye+ONN9ZZX11dXVyVVLvS6cPH62vjn//8Z6P3de3atXj8+uuvb1iHm8l2222XE088MbfddltmzZqVBQsW5Pbbb89BBx2UJPnrX/+a8847r6x9BAAAGidwAgAAKLOnnnoq1dXVa61/+umni+8y6t+/f/H8nnvuWdzG7i9/+cs6P2P69OnF47ptDBw4sLg66s9//vPGd74Z9ejRI2PGjMm0adNy4IEHJknuu+++VFVVlblnAADAhwmcAAAAyuytt97KpEmT1lp/++23F4+POuqo4nHr1q1zxBFHJEkefPDBzJs3b61t3HrrrcV7PvWpTxXP77zzzjnkkEOSJL/+9a+zYMGCTXqG5tSmTZvic1ZXV+edd94pb4cAAIAGBE4AAABbgG9/+9uNbotXWVmZm2++OUly0EEHZfDgwfXqv/71rydJVqxYkbPPPjsrV65s0Mbtt9+eBx54IEly0kknpUePHvXqL7300iTJsmXLcsopp+Tdd99daz/XFWptqocffjgvv/zyWutXrFiRysrKJEnnzp3TrVu3Ju8DAABQmtbl7gAAAMDW7s0338xzzz233us6dOiQvfbaq8H5AQMG5Pnnn89BBx2Uyy+/PEOGDMkHH3yQ+++/P9dee22qq6vTunXr3HjjjQ3uPe6443LKKafk7rvvzgMPPJCDDz443/72t7P33nvn7bffzoQJE4orpHbeeef8/Oc/b9DG8ccfn7PPPju33XZbHnvssey777658MILc+ihh2aHHXbIokWLMmPGjNx1110ZMGBAxo0bt/H/I63Dn/70p/zoRz/KsGHDctxxx2X//fdPt27dUlVVlZdeeim/+MUv8uSTTyZJzj777LRu7UdZAADY0vguHQAAoEQ33XRTbrrppvVeN2DAgDz11FMNzh9wwAG58MILc/755+fCCy9sUN+2bdv88pe/zCc/+clG2x0/fnyqq6tz77335sknn8zpp5/e4JqePXtm8uTJ2XXXXRttY+zYsenQoUNuvPHGLFiwIFdcccVan6E5rF69OpWVlcWVTI054YQT8pOf/KRZPh8AACiNwAkAAGALcM4556R///659tpr88gjj2TRokXp1q1bRowYkUsvvTT77rvvWu9t37597rnnnkyaNCnjxo3L448/nkWLFqVTp07p169fTjzxxFx44YXp3LnzWtvYbrvtcsMNN2TMmDEZO3Zspk6dmvnz52fFihX5yEc+kv333z+f+cxn8pWvfKXJn/1f/uVfsv/++2fKlCmZOXNmFixYkDfffDNJsssuu2TIkCE544wzctxxxzX5ZwMAAE2joqampqbcnQAAAGiJ+vTpk1dffTWjR49u8m3qAAAANqdW5e4AAAAAAAAAWzeBEwAAAAAAACUROAEAAAAAAFASgRMAAAAAAAAlETgBAAAAAABQkoqampqacncCAAAAAACArZcVTgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEkETgAAAAAAAJRE4AQAAAAAAEBJBE4AAAAAAACUROAEAAAAAABASQROAAAAAAAAlETgBAAAAAAAQEn+P6v73htiHywrAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1000x700 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 602,
       "width": 846
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%config InlineBackend.figure_format='retina'\n",
    "plt.figure(figsize=(10, 7))\n",
    "plt.plot(train_loss_list, color=\"blue\", linestyle=\"-\", label=\"train loss\")\n",
    "plt.plot(valid_loss_list, color=\"red\", linestyle=\"-\", label=\"valid loss\")\n",
    "plt.xlabel(\"Epochs\")\n",
    "plt.ylabel(\"Loss\")\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a099cfa1",
   "metadata": {},
   "source": [
    "## 5. 模型评估\n",
    "\n",
    "在这一部分，我们将使用测试集上的方程准确率对模型进行评估。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "4ed945b2",
   "metadata": {},
   "outputs": [],
   "source": [
    "def equation_accuracy(preds, tgts):\n",
    "    correct = 0\n",
    "    for tgt, pred in zip(tgts, preds):\n",
    "        if tgt == pred:\n",
    "            correct += 1\n",
    "    return correct / len(tgts)\n",
    "\n",
    "\n",
    "@torch.no_grad()\n",
    "def greedy_decode(model, src, max_len, start_symbol):\n",
    "    src = src.to(DEVICE)\n",
    "    ys = torch.ones(1, 1).fill_(start_symbol).type(torch.long).to(DEVICE)\n",
    "    src_mask, tgt_mask, src_padding_mask, _ = create_mask(src, ys)\n",
    "\n",
    "    memory = model.encode(src, src_mask, src_padding_mask)\n",
    "\n",
    "    for i in range(max_len - 1):\n",
    "        tgt_mask = torch.ones((ys.shape[1], ys.shape[1]), dtype=torch.bool, device=DEVICE).triu_(diagonal=1)\n",
    "\n",
    "        out = model.decode(ys, memory, tgt_mask)\n",
    "\n",
    "        prob = model.generator(out[:, -1])\n",
    "        _, next_word = torch.max(prob, dim=1)\n",
    "        next_word = next_word.item()\n",
    "\n",
    "        ys = torch.cat([ys, torch.ones(1, 1).fill_(next_word).type(torch.long).to(DEVICE)], dim=1)\n",
    "        if next_word == tgt_vocab[\"<eos>\"]:\n",
    "            break\n",
    "    return ys\n",
    "\n",
    "\n",
    "@torch.no_grad()\n",
    "def inference(model, problem):\n",
    "    model.eval()\n",
    "    src = preprocess_sentence(problem, src_vocab, 120)\n",
    "    src = src.unsqueeze(0)\n",
    "    tgt_tokens = greedy_decode(model, src, max_len=50, start_symbol=tgt_vocab[\"<bos>\"]).flatten()\n",
    "    return \"\".join(tgt_vocab.to_tokens(tgt_tokens.tolist())).replace(\"<bos>\", \"\").replace(\"<eos>\", \"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "e31fd340",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "问题 1: 在一正方形花池的四周栽了temp_a棵柳树，每两棵柳树之间的间隔是temp_b米，这个正方形的周长=多少米？\n",
      "真实方程: temp_a*temp_b\n",
      "预测方程: temp_b*temp_a\n",
      "--------------------\n",
      "问题 2: 张明有temp_a元钱，买书用去temp_b%，买文具的钱是买书的temp_c%．买文具用去多少元？\n",
      "真实方程: temp_a*temp_b*temp_c\n",
      "预测方程: temp_a*temp_b*temp_c\n",
      "--------------------\n",
      "问题 3: 一个工厂要生产temp_a个零件，前temp_b天生产了temp_c个，剩下的要在temp_d天内完成，平均每天生产多少个？\n",
      "真实方程: (temp_a-temp_c)/temp_d\n",
      "预测方程: (temp_a-temp_c*temp_b)/temp_d\n",
      "--------------------\n",
      "问题 4: 一本字典定价temp_a元，temp_b出售后还赚temp_c%，这本字典进价=多少元．\n",
      "真实方程: temp_a*temp_b/(1+temp_c)\n",
      "预测方程: (temp_a+temp_c)/(1+temp_b)\n",
      "--------------------\n",
      "问题 5: 修一段长temp_a米的路，前temp_b小时共修了temp_c米，剩下的每小时修temp_d米，还要几小时才能修完？\n",
      "真实方程: (temp_a-temp_c)/temp_d\n",
      "预测方程: (temp_a-temp_c*temp_b)/temp_d\n",
      "--------------------\n"
     ]
    }
   ],
   "source": [
    "for i in range(5):\n",
    "    problem, equation = test_problems[i], test_equations[i]\n",
    "    print(f\"问题 {i+1}: {''.join(problem)}\")\n",
    "    print(f\"真实方程: {''.join(equation)}\")\n",
    "    print(f\"预测方程: {inference(model, problem)}\")\n",
    "    print(\"-\" * 20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "d0dc7ad5",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 1000/1000 [00:10<00:00, 96.42it/s]\n"
     ]
    }
   ],
   "source": [
    "from tqdm import tqdm\n",
    "\n",
    "test_loader = DataLoader(test_dataset, batch_size=1)\n",
    "preds, tgts = [], []\n",
    "for src, tgt in tqdm(test_loader):\n",
    "    pred = greedy_decode(model, src, max_len=50, start_symbol=tgt_vocab[\"<bos>\"]).flatten()\n",
    "    pred = tgt_vocab.to_tokens(pred.tolist())\n",
    "    preds.append(\"\".join(pred).replace(\"<bos>\", \"\").replace(\"<eos>\", \"\").replace(\"<pad>\", \"\"))\n",
    "    tgts.append(\n",
    "        \"\".join(tgt_vocab.to_tokens(tgt[0].tolist())).replace(\"<bos>\", \"\").replace(\"<eos>\", \"\").replace(\"<pad>\", \"\")\n",
    "    )\n",
    "acc = equation_accuracy(preds, tgts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "68903156",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "方程准确率: 0.331\n"
     ]
    }
   ],
   "source": [
    "print(f\"方程准确率: {acc:.3f}\")"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": "dl",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
